*** empty log message ***
authorElliot Lee <sopwith@src.gnome.org>
Tue, 20 Jun 2000 20:20:38 +0000 (20:20 +0000)
committerElliot Lee <sopwith@src.gnome.org>
Tue, 20 Jun 2000 20:20:38 +0000 (20:20 +0000)
28 files changed:
gdk/gdkdnd.h
gdk/gdkdraw.c
gdk/gdkevents.c
gdk/gdkevents.h
gdk/gdkgc.h
gdk/gdkprivate.h
gdk/gdkregion-generic.h
gdk/gdktypes.h
gdk/gdkwindow.c
gdk/linux-fb/Makefile.am
gdk/linux-fb/gdkcursor-fb.c
gdk/linux-fb/gdkdrawable-fb2.c
gdk/linux-fb/gdkevents-fb.c
gdk/linux-fb/gdkfb.h
gdk/linux-fb/gdkfont-fb.c
gdk/linux-fb/gdkgc-fb.c
gdk/linux-fb/gdkgeometry-fb.c
gdk/linux-fb/gdkimage-fb.c
gdk/linux-fb/gdkinput-ps2.c
gdk/linux-fb/gdkmain-fb.c
gdk/linux-fb/gdkpixmap-fb.c
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkvisual-fb.c
gdk/linux-fb/gdkwindow-fb.c
gdk/x11/gdkgc-x11.c
gdk/x11/gdkpixmap-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkx.h

index 30f2f131f7ccf19bacbfcb6c07b2fc484428004c..657e00c8204b2f896416306452c7251fec372b99 100644 (file)
@@ -27,7 +27,8 @@ typedef enum
                                   * drags */
   GDK_DRAG_PROTO_NONE,           /* Not a valid drag window */
   GDK_DRAG_PROTO_WIN32_DROPFILES, /* The simple WM_DROPFILES dnd */
-  GDK_DRAG_PROTO_OLE2            /* The complex OLE2 dnd (not implemented) */
+  GDK_DRAG_PROTO_OLE2,           /* The complex OLE2 dnd (not implemented) */
+  GDK_DRAG_PROTO_LOCAL            /* Intra-app */
 } GdkDragProtocol;
 
 /* Structure that holds information about a drag in progress.
index 6af7a7e2ec6d4452bba2690f2c36da80252a9032..ceb3db0d1bdc4a4df4f390833259b0ffaaf80782 100644 (file)
@@ -375,7 +375,6 @@ gdk_draw_image (GdkDrawable *drawable,
   if (height == -1)
     height = image->height;
 
-
   if (GDK_IS_WINDOW (drawable))
     _gdk_window_draw_image (drawable, gc, image, xsrc, ysrc,
                            xdest, ydest, width, height);
index 5dabc26108563ba6aea312af6a0760c39b3c8092..86658bc449a005d592ba0305f70ad9845f0b5d76 100644 (file)
@@ -135,7 +135,6 @@ gdk_event_queue_remove_link (GList *node)
     node->next->prev = node->prev;
   else
     gdk_queued_tail = node->prev;
-  
 }
 
 /*************************************************************
index 20536f08bc9a2ca13aae4017c86b079bfc03a11d..9997fbee2c9d05095a4b10aae682ca21d0205ccd 100644 (file)
@@ -342,8 +342,8 @@ struct _GdkEventSelection
   GdkAtom selection;
   GdkAtom target;
   GdkAtom property;
-  guint32 requestor;
   guint32 time;
+  GdkNativeWindow requestor;
 };
 
 /* This event type will be used pretty rarely. It only is important
index 072ddfe74e49303966ff838655b8d8b713d34d91..95eaa15ad1ad24a86e07212639089f2e5b6a47aa 100644 (file)
@@ -73,6 +73,7 @@ typedef enum
   GDK_COPY_INVERT,
   GDK_OR_INVERT,
   GDK_NAND,
+  GDK_NOR,
   GDK_SET
 } GdkFunction;
 
index ef92a2663ccd155efed1d8de25e2ea82fccb5fe8..f882c35829b667fe7966dd4fc6c8d4aeef9ee9d7 100644 (file)
@@ -49,10 +49,9 @@ extern "C" {
                           GDK_DRAWABLE_TYPE(d) == GDK_WINDOW_FOREIGN)
 #define GDK_IS_PIXMAP(d) (GDK_DRAWABLE_TYPE(d) == GDK_DRAWABLE_PIXMAP)
 #define GDK_DRAWABLE_DESTROYED(d) (((GdkDrawablePrivate *)d)->destroyed)
-
-#define gdk_window_lookup(xid)    ((GdkWindow*) gdk_xid_table_lookup (xid))
-#define gdk_pixmap_lookup(xid)    ((GdkPixmap*) gdk_xid_table_lookup (xid))
-#define gdk_font_lookup(xid)      ((GdkFont*) gdk_xid_table_lookup (xid))
+#define GDK_DRAWABLE_P(d) ((GdkDrawablePrivate*)d)
+#define GDK_WINDOW_P(d) ((GdkWindowPrivate*)d)
+#define GDK_GC_P(d) ((GdkGCPrivate*)d)
 
 typedef struct _GdkDrawablePrivate     GdkDrawablePrivate;
 typedef struct _GdkWindowPrivate       GdkWindowPrivate;
index 659d44eb4cdcfb999fa685bfddfa7e91ed52a87b..017ee43e2c8826f618b98ba6572e809b1a9dd1c3 100644 (file)
@@ -45,12 +45,9 @@ SOFTWARE.
 #ifndef __GDK_REGION_GENERIC_H__
 #define __GDK_REGION_GENERIC_H__
 
-typedef struct _GdkRegionBox GdkRegionBox;
+#include "gdktypes.h"
 
-struct _GdkRegionBox
-{
-  int x1, x2, y1, y2;
-};
+typedef GdkSegment GdkRegionBox;
 
 /* 
  *   clip region
index 394b7a5d38dfe28cf8e8631edceb1b1b3cb26a45..a4055e2d70053626cfaccfdf7caeb78c7e7928c6 100644 (file)
@@ -76,6 +76,12 @@ typedef struct _GdkSegment         GdkSegment;
  */
 typedef guint32                            GdkWChar;
 typedef gulong                     GdkAtom;
+
+#ifdef GDK_NATIVE_WINDOW_POINTER
+typedef gpointer GdkNativeWindow;
+#else
+typedef guint32 GdkNativeWindow;
+#endif
  
 /* Forward declarations of commonly used types
  */
index 6af552daa73b22d5caf38fbfcc9ad1f0556805a5..ff25f7f70ada46aeaeec2a3cf5ff38a065e5eac9 100644 (file)
@@ -657,7 +657,7 @@ gdk_window_begin_paint_region (GdkWindow *window,
            {
              tmp_paint = private->paint_stack->data;
              gdk_region_subtract (init_region, tmp_paint->region);
-             
+
              tmp_list = tmp_list->next;
            }
        }
@@ -745,6 +745,7 @@ gdk_window_free_paint_stack (GdkWindow *window)
       while (tmp_list)
        {
          GdkWindowPaint *paint = tmp_list->data;
+
          if (tmp_list == private->paint_stack)
            gdk_drawable_unref (paint->pixmap);
                  
@@ -1119,6 +1120,7 @@ gdk_window_draw_glyphs (GdkDrawable      *drawable,
   if (private->paint_stack)
     {
       GdkWindowPaint *paint = private->paint_stack->data;
+
       gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs);
     }
   else
index ace052e06f63b69741fc8befed2d90f4b56a890b..21462c16284b431d56bc4ab721322d47013ce285 100644 (file)
@@ -9,23 +9,22 @@ INCLUDES = @STRIP_BEGIN@      \
        @GTK_XIM_FLAGS@         \
        @GTK_LOCALE_FLAGS@      \
        @GLIB_CFLAGS@           \
+       @PANGO_CFLAGS@          \
 @STRIP_END@
 
 LDFLAGS = @STRIP_BEGIN@ \
        @GLIB_LIBS@     \
-       -L/gnome2/lib   \
-       -lt1            \
+       @PANGO_CFLAGS@  \
+       -lfreetype      \
        -lm             \
 @STRIP_END@
 
-if USE_LINUX_FB
+noinst_LTLIBRARIES = libgdk-linux-fb.la
+noinst_PROGRAMS=#test-fb
 
-lib_LTLIBRARIES = libgdk-fb.la
-noinst_PROGRAMS=test-fb
+#test_fb_LDFLAGS=../libgdk.la libgdk-linux-fb.la
 
-test_fb_LDFLAGS=../libgdk.la libgdk-fb.la
-
-libgdk_fb_la_SOURCES =         \
+libgdk_linux_fb_la_SOURCES =           \
        gdkcolor-fb.c           \
        gdkcursor-fb.c          \
        gdkdnd-fb.c             \
@@ -57,10 +56,6 @@ libgdk_fb_la_SOURCES =       \
        miwideline.c            \
        mizerclip.c             \
        mizerline.c             \
+       mispans.c               \
+       gdkpango-fb.c
        mispans.c
-else
-lib_LTLIBRARIES =
-noinst_PROGRAMS=
-
-endif
-
index 8a883f9e87c8b3bdb44aaee410e2b96f8624942c..1184259dd3d65fe1522d4a79d181fad76e203c4b 100644 (file)
 #include "gdkprivate-fb.h"
 #include "gdkcursor.h"
 
+#include "/home/sopwith/bin/t.xbm"
+
+static struct {
+  const guchar *bits;
+  int width, height, hotx, hoty;
+  GdkPixmap *pm;
+} stock_cursors[] = {
+  {X_cursor_bits, 14, 14, 6, 8},
+  {X_cursor_mask_bits, 16, 16, 7, 9},
+  {arrow_bits, 14, 14, 13, 14},
+  {arrow_mask_bits, 16, 16, 14, 15},
+  {based_arrow_down_bits, 8, 10, 3, 1},
+  {based_arrow_down_mask_bits, 10, 12, 4, 2},
+  {based_arrow_up_bits, 8, 10, 3, 1},
+  {based_arrow_up_mask_bits, 10, 12, 4, 2},
+  {boat_bits, 16, 8, 14, 5},
+  {boat_mask_bits, 16, 9, 14, 5},
+  {bogosity_bits, 13, 14, 6, 8},
+  {bogosity_mask_bits, 15, 16, 7, 9},
+  {bottom_left_corner_bits, 14, 14, 0, 1},
+  {bottom_left_corner_mask_bits, 16, 16, 1, 2},
+  {bottom_right_corner_bits, 14, 14, 13, 1},
+  {bottom_right_corner_mask_bits, 16, 16, 14, 2},
+  {bottom_side_bits, 13, 14, 6, 1},
+  {bottom_side_mask_bits, 15, 16, 7, 2},
+  {bottom_tee_bits, 14, 10, 7, 1},
+  {bottom_tee_mask_bits, 16, 12, 8, 2},
+  {box_spiral_bits, 15, 16, 8, 8},
+  {box_spiral_mask_bits, 16, 16, 8, 8},
+  {center_ptr_bits, 10, 14, 4, 14},
+  {center_ptr_mask_bits, 12, 16, 5, 15},
+  {circle_bits, 14, 14, 7, 7},
+  {circle_mask_bits, 16, 16, 8, 8},
+  {clock_bits, 14, 16, 6, 13},
+  {clock_mask_bits, 15, 16, 6, 13},
+  {coffee_mug_bits, 15, 16, 7, 7},
+  {coffee_mug_mask_bits, 16, 16, 7, 7},
+  {cross_bits, 16, 15, 7, 8},
+  {cross_mask_bits, 16, 16, 7, 9},
+  {cross_reverse_bits, 16, 15, 7, 8},
+  {cross_reverse_mask_bits, 16, 15, 7, 8},
+  {crosshair_bits, 16, 15, 7, 8},
+  {crosshair_mask_bits, 16, 16, 7, 9},
+  {diamond_cross_bits, 15, 15, 7, 8},
+  {diamond_cross_mask_bits, 16, 16, 7, 9},
+  {dot_bits, 10, 10, 5, 5},
+  {dot_mask_bits, 12, 12, 6, 6},
+  {dotbox_bits, 12, 12, 6, 7},
+  {dotbox_mask_bits, 14, 14, 7, 8},
+  {double_arrow_bits, 10, 14, 5, 7},
+  {double_arrow_mask_bits, 12, 16, 6, 8},
+  {draft_large_bits, 15, 15, 14, 15},
+  {draft_large_mask_bits, 15, 16, 14, 16},
+  {draft_small_bits, 15, 15, 14, 15},
+  {draft_small_mask_bits, 15, 15, 14, 15},
+  {draped_box_bits, 12, 12, 6, 7},
+  {draped_box_mask_bits, 14, 14, 7, 8},
+  {exchange_bits, 14, 14, 6, 8},
+  {exchange_mask_bits, 16, 16, 7, 9},
+  {fleur_bits, 14, 14, 7, 7},
+  {fleur_mask_bits, 16, 16, 8, 8},
+  {gobbler_bits, 16, 15, 14, 13},
+  {gobbler_mask_bits, 16, 16, 14, 13},
+  {gumby_bits, 16, 16, 2, 16},
+  {gumby_mask_bits, 16, 16, 2, 16},
+  {hand1_bits, 13, 16, 12, 16},
+  {hand1_mask_bits, 13, 16, 12, 16},
+  {hand2_bits, 15, 14, 0, 14},
+  {hand2_mask_bits, 16, 16, 0, 15},
+  {heart_bits, 15, 14, 6, 6},
+  {heart_mask_bits, 15, 14, 6, 6},
+  {icon_bits, 16, 16, 8, 8},
+  {icon_mask_bits, 16, 16, 8, 8},
+  {iron_cross_bits, 14, 14, 7, 8},
+  {iron_cross_mask_bits, 16, 16, 8, 9},
+  {left_ptr_bits, 8, 14, 0, 14},
+  {left_ptr_mask_bits, 10, 16, 1, 15},
+  {left_side_bits, 14, 13, 0, 7},
+  {left_side_mask_bits, 16, 15, 1, 8},
+  {left_tee_bits, 10, 14, 0, 7},
+  {left_tee_mask_bits, 12, 16, 1, 8},
+  {leftbutton_bits, 16, 16, 8, 8},
+  {leftbutton_mask_bits, 15, 16, 8, 8},
+  {ll_angle_bits, 10, 10, 0, 1},
+  {ll_angle_mask_bits, 12, 12, 1, 2},
+  {lr_angle_bits, 10, 10, 9, 1},
+  {lr_angle_mask_bits, 12, 12, 10, 2},
+  {man_bits, 16, 16, 14, 11},
+  {man_mask_bits, 16, 16, 14, 11},
+  {middlebutton_bits, 16, 16, 8, 8},
+  {middlebutton_mask_bits, 15, 16, 8, 8},
+  {mouse_bits, 15, 14, 4, 13},
+  {mouse_mask_bits, 16, 16, 4, 15},
+  {pencil_bits, 11, 16, 10, 1},
+  {pencil_mask_bits, 13, 16, 11, 1},
+  {pirate_bits, 15, 16, 7, 4},
+  {pirate_mask_bits, 16, 16, 7, 4},
+  {plus_bits, 10, 10, 4, 5},
+  {plus_mask_bits, 12, 12, 5, 6},
+  {question_arrow_bits, 9, 15, 4, 8},
+  {question_arrow_mask_bits, 11, 16, 5, 8},
+  {right_ptr_bits, 8, 14, 7, 14},
+  {right_ptr_mask_bits, 10, 16, 8, 15},
+  {right_side_bits, 14, 13, 13, 7},
+  {right_side_mask_bits, 16, 15, 14, 8},
+  {right_tee_bits, 10, 14, 9, 7},
+  {right_tee_mask_bits, 12, 16, 10, 8},
+  {rightbutton_bits, 16, 16, 8, 8},
+  {rightbutton_mask_bits, 15, 16, 8, 8},
+  {rtl_logo_bits, 14, 14, 6, 8},
+  {rtl_logo_mask_bits, 16, 16, 7, 9},
+  {sailboat_bits, 12, 13, 6, 14},
+  {sailboat_mask_bits, 16, 16, 8, 16},
+  {sb_down_arrow_bits, 7, 15, 3, 0},
+  {sb_down_arrow_mask_bits, 9, 16, 4, 1},
+  {sb_h_double_arrow_bits, 15, 7, 7, 4},
+  {sb_h_double_arrow_mask_bits, 15, 9, 7, 5},
+  {sb_left_arrow_bits, 15, 7, -1, 4},
+  {sb_left_arrow_mask_bits, 16, 9, 0, 5},
+  {sb_right_arrow_bits, 15, 7, 15, 4},
+  {sb_right_arrow_mask_bits, 16, 9, 15, 5},
+  {sb_up_arrow_bits, 7, 15, 3, 16},
+  {sb_up_arrow_mask_bits, 9, 16, 4, 16},
+  {sb_v_double_arrow_bits, 7, 15, 3, 8},
+  {sb_v_double_arrow_mask_bits, 9, 15, 4, 8},
+  {shuttle_bits, 15, 16, 10, 16},
+  {shuttle_mask_bits, 16, 16, 11, 16},
+  {sizing_bits, 14, 14, 7, 7},
+  {sizing_mask_bits, 16, 16, 8, 8},
+  {spider_bits, 16, 16, 6, 9},
+  {spider_mask_bits, 16, 16, 6, 9},
+  {spraycan_bits, 11, 16, 9, 14},
+  {spraycan_mask_bits, 12, 16, 10, 14},
+  {star_bits, 15, 16, 7, 9},
+  {star_mask_bits, 16, 16, 7, 9},
+  {target_bits, 15, 13, 7, 7},
+  {target_mask_bits, 16, 14, 7, 7},
+  {tcross_bits, 13, 13, 6, 7},
+  {tcross_mask_bits, 15, 15, 7, 8},
+  {top_left_arrow_bits, 14, 14, 0, 14},
+  {top_left_arrow_mask_bits, 16, 16, 1, 15},
+  {top_left_corner_bits, 14, 14, 0, 14},
+  {top_left_corner_mask_bits, 16, 16, 1, 15},
+  {top_right_corner_bits, 14, 14, 13, 14},
+  {top_right_corner_mask_bits, 16, 16, 14, 15},
+  {top_side_bits, 13, 14, 6, 14},
+  {top_side_mask_bits, 15, 16, 7, 15},
+  {top_tee_bits, 14, 10, 7, 10},
+  {top_tee_mask_bits, 16, 12, 8, 11},
+  {trek_bits, 7, 16, 3, 16},
+  {trek_mask_bits, 9, 16, 4, 16},
+  {ul_angle_bits, 10, 10, 0, 10},
+  {ul_angle_mask_bits, 12, 12, 1, 11},
+  {umbrella_bits, 14, 14, 7, 12},
+  {umbrella_mask_bits, 16, 16, 8, 14},
+  {ur_angle_bits, 10, 10, 9, 10},
+  {ur_angle_mask_bits, 12, 12, 10, 11},
+  {watch_bits, 16, 16, 15, 7},
+  {watch_mask_bits, 16, 16, 15, 7},
+  {xterm_bits, 7, 14, 3, 7},
+  {xterm_mask_bits, 9, 16, 4, 8}
+};
+
 GdkCursor*
 gdk_cursor_new (GdkCursorType cursor_type)
 {
-  GdkCursorPrivateFB *private;
-  GdkCursor *cursor;
+  GdkPixmap *pm, *mask;
 
-  return NULL;
+  if(cursor_type >= sizeof(stock_cursors)/sizeof(stock_cursors[0]))
+    return NULL;
 
-  private = g_new0(GdkCursorPrivateFB, 1);
-  cursor = (GdkCursor*) private;
-  cursor->type = cursor_type;
-  cursor->ref_count = 1;
-  
-  return cursor;
+  pm = stock_cursors[cursor_type].pm;
+  if(!pm)
+    {
+      pm = stock_cursors[cursor_type].pm = gdk_bitmap_create_from_data(gdk_parent_root,
+                                                                      stock_cursors[cursor_type].bits,
+                                                                      stock_cursors[cursor_type].width,
+                                                                      stock_cursors[cursor_type].height);
+      gdk_pixmap_ref(pm);
+    }
+  mask = stock_cursors[cursor_type+1].pm;
+  if(!mask)
+    {
+      mask = stock_cursors[cursor_type+1].pm = gdk_bitmap_create_from_data(gdk_parent_root,
+                                                                          stock_cursors[cursor_type+1].bits,
+                                                                          stock_cursors[cursor_type+1].width,
+                                                                          stock_cursors[cursor_type+1].height);
+      gdk_pixmap_ref(mask);
+    }
+
+  return gdk_cursor_new_from_pixmap(pm, mask, NULL, NULL,
+                                   stock_cursors[cursor_type].hotx,
+                                   stock_cursors[cursor_type].hoty);
 }
 
 GdkCursor*
@@ -63,6 +242,8 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
   cursor->ref_count = 1;
   private->cursor = gdk_pixmap_ref(source);
   private->mask = gdk_pixmap_ref(mask);
+  private->hot_x = x;
+  private->hot_y = y;
   
   return cursor;
 }
index 99d158f749c5721129cb18ca69b8cfc67f417ede..81ef83091a10c831c02e665178768cfaf2a3fe04 100644 (file)
@@ -1,11 +1,21 @@
 #include "gdkprivate-fb.h"
 #include "mi.h"
-#include <t1lib.h>
+
+/* #define USE_FTGRAYS */
+#define USE_AA
+#include <freetype/ftglyph.h>
+
+#include <endian.h>
+#ifndef __BYTE_ORDER
+#error "endian.h needs to #define __BYTE_ORDER"
+#endif
 
 #ifndef g_alloca
 #define g_alloca alloca
 #endif
 
+static void gdk_fb_drawable_set_pixel(GdkDrawable *drawable, GdkGC *gc, int x, int y, GdkColor *spot, gboolean abs_coords);
+
 static void gdk_fb_drawable_destroy   (GdkDrawable     *drawable);
 void gdk_fb_draw_rectangle (GdkDrawable    *drawable,
                            GdkGC          *gc,
@@ -42,6 +52,12 @@ static void gdk_fb_draw_text_wc   (GdkDrawable    *drawable,
                                   gint            y,
                                   const GdkWChar *text,
                                   gint            text_length);
+static void gdk_fb_draw_glyphs(GdkDrawable      *drawable,
+                              GdkGC               *gc,
+                              PangoFont        *font,
+                              gint              x,
+                              gint              y,
+                              PangoGlyphString *glyphs);
 void gdk_fb_draw_drawable  (GdkDrawable    *drawable,
                            GdkGC          *gc,
                            GdkPixmap      *src,
@@ -75,7 +91,8 @@ GdkDrawableClass _gdk_fb_drawable_class = {
   gdk_fb_draw_drawable,
   gdk_fb_draw_points,
   gdk_fb_draw_segments,
-  gdk_fb_draw_lines
+  gdk_fb_draw_lines,
+  gdk_fb_draw_glyphs
 };
 
 /*****************************************************
@@ -184,12 +201,10 @@ gdk_fb_clip_region(GdkDrawable *drawable, GdkGC *gc, gboolean do_clipping)
 }
 
 static void
-gdk_fb_fill_span(GdkDrawable *drawable, GdkGC *gc, GdkSegment *cur, guint pixel, GdkVisual *visual)
+gdk_fb_fill_span(GdkDrawable *drawable, GdkGC *gc, GdkSegment *cur, GdkColor *color, GdkVisual *visual)
 {
   int curx, cury;
-  guchar *mem = GDK_DRAWABLE_FBDATA(drawable)->mem;
-  guint rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride;
-  guint depth = GDK_DRAWABLE_P(drawable)->depth;
+  GdkColor spot = *color;
 
   if(gc
      && (GDK_GC_FBDATA(gc)->values.clip_mask
@@ -218,6 +233,10 @@ gdk_fb_fill_span(GdkDrawable *drawable, GdkGC *gc, GdkSegment *cur, guint pixel,
        {
          gint xstep, ystep;
          gint relx, rely;
+         GdkFBDrawingContext *dc, dc_data;
+         dc = &dc_data;
+
+         gdk_fb_drawing_context_init(dc, drawable, gc, FALSE, TRUE);
 
          ts = GDK_GC_FBDATA(gc)->values.tile;
          for(cury = cur->y1; cury < cur->y2; cury += ystep)
@@ -243,13 +262,16 @@ gdk_fb_fill_span(GdkDrawable *drawable, GdkGC *gc, GdkSegment *cur, guint pixel,
 
                  xstep = MIN(GDK_DRAWABLE_P(ts)->width - draww, cur->x2 - relx);
 
-                 gdk_fb_draw_drawable_2(drawable, gc, ts,
+                 gdk_fb_draw_drawable_3(drawable, gc, ts,
+                                        dc,
                                         draww, drawh,
                                         relx, rely,
-                                        xstep, ystep, FALSE, TRUE);
+                                        xstep, ystep);
                }
            }
 
+         gdk_fb_drawing_context_finalize(dc);
+
          return;
        }
       else if((GDK_GC_FBDATA(gc)->values.fill == GDK_STIPPLED
@@ -262,163 +284,165 @@ gdk_fb_fill_span(GdkDrawable *drawable, GdkGC *gc, GdkSegment *cur, guint pixel,
          solid_stipple = (GDK_GC_FBDATA(gc)->values.fill == GDK_OPAQUE_STIPPLED);
        }
 
-      switch(depth)
+      for(cury = cur->y1; cury < cur->y2; cury++)
        {
-       case 1:
-         g_assert(!ts);
-         for(cury = cur->y1; cury < cur->y2; cury++)
+         for(curx = cur->x1; curx < cur->x2; curx++)
            {
-             for(curx = cur->x1; curx < cur->x2; curx++)
-               {
-                 guchar *ptr = mem + (cury * rowstride) + (curx >> 3);
-                 int maskx = curx+clipxoff, masky = cury + clipyoff;
-                 guchar foo;
-
-                 if(cmask)
-                   {
-                     foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
+             int maskx = curx+clipxoff, masky = cury + clipyoff;
+             guchar foo;
 
-                     if(!(foo & (1 << (maskx % 8))))
-                       continue;
-                   }
-
-                 *ptr |= (1 << (curx % 8));
-               }
-           }
-         break;
-       case 8:
-         for(cury = cur->y1; cury < cur->y2; cury++)
-           {
-             for(curx = cur->x1; curx < cur->x2; curx++)
+             if(cmask)
                {
-                 guchar *ptr = mem + (cury * rowstride) + curx;
-                 int maskx = curx+clipxoff, masky = cury + clipyoff;
-                 guchar foo;
+                 foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
 
-                 if(cmask)
-                   {
-                     foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
-
-                     if(!(foo & (1 << (maskx % 8))))
-                       continue;
-                   }
-
-                 if(ts)
-                   {
-                     int wid = GDK_DRAWABLE_P(ts)->width, hih = GDK_DRAWABLE_P(ts)->height;
-                     maskx = (curx+tsxoff)%wid;
-                     masky = (cury+tsyoff)%hih;
-                     if(maskx < 0)
-                       maskx += wid;
-                     if(masky < 0)
-                       masky += hih;
-
-                     foo = GDK_DRAWABLE_FBDATA(ts)->mem[(maskx >> 3) + GDK_DRAWABLE_FBDATA(ts)->rowstride*masky];
-                     if(foo & (1 << (maskx % 8)))
-                       {
-                         pixel = GDK_GC_FBDATA(gc)->values.foreground.pixel;
-                       }
-                     else if(solid_stipple)
-                       {
-                         pixel = GDK_GC_FBDATA(gc)->values.background.pixel;
-                       }
-                     else
-                       continue;
-                   }
-
-                 *ptr = pixel;
+                 if(!(foo & (1 << (maskx % 8))))
+                   continue;
                }
-           }
-         break;
 
-       case 16:
-       case 24:
-       case 32:
-         for(cury = cur->y1; cury < cur->y2; cury++)
-           {
-             for(curx = cur->x1; curx < cur->x2; curx++)
+             if(ts)
                {
-                 guint *ptr2 = (guint *)(mem + (cury * rowstride) + (curx * (depth >> 3)));
-                 int maskx = curx+clipxoff, masky = cury + clipyoff;
-                 guchar foo;
+                 int wid = GDK_DRAWABLE_P(ts)->width, hih = GDK_DRAWABLE_P(ts)->height;
 
-                 if(cmask)
-                   {
-                     foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
+                 maskx = (curx+tsxoff)%wid;
+                 masky = (cury+tsyoff)%hih;
+                 if(maskx < 0)
+                   maskx += wid;
+                 if(masky < 0)
+                   masky += hih;
 
-                     if(!(foo & (1 << (maskx % 8))))
-                       continue;
+                 foo = GDK_DRAWABLE_FBDATA(ts)->mem[(maskx >> 3) + GDK_DRAWABLE_FBDATA(ts)->rowstride*masky];
+                 if(foo & (1 << (maskx % 8)))
+                   {
+                     spot = GDK_GC_FBDATA(gc)->values.foreground;
                    }
-
-                 if(ts)
+                 else if(solid_stipple)
                    {
-                     int wid = GDK_DRAWABLE_P(ts)->width, hih = GDK_DRAWABLE_P(ts)->height;
-
-                     maskx = (curx+tsxoff)%wid;
-                     masky = (cury+tsyoff)%hih;
-                     if(maskx < 0)
-                       maskx += wid;
-                     if(masky < 0)
-                       masky += hih;
-
-                     foo = GDK_DRAWABLE_FBDATA(ts)->mem[(maskx >> 3) + GDK_DRAWABLE_FBDATA(ts)->rowstride*masky];
-                     if(foo & (1 << (maskx % 8)))
-                       {
-                         pixel = GDK_GC_FBDATA(gc)->values.foreground.pixel;
-                       }
-                     else if(solid_stipple)
-                       {
-                         pixel = GDK_GC_FBDATA(gc)->values.background.pixel;
-                       }
-                     else
-                       continue;
+                     spot = GDK_GC_FBDATA(gc)->values.background;
                    }
-
-                 *ptr2 = (*ptr2 & ~(visual->red_mask|visual->green_mask|visual->blue_mask)) | pixel;
+                 else
+                   continue;
                }
+
+             gdk_fb_drawable_set_pixel(drawable, gc, curx, cury, &spot, TRUE);
            }
-         break;
        }
     }
   else
     {
-      switch(depth)
+      guchar *mem = GDK_DRAWABLE_FBDATA(drawable)->mem, *ptr;
+      guint rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride;
+      int n;
+
+      switch(GDK_DRAWABLE_P(drawable)->depth)
        {
        case 1:
-         for(cury = cur->y1; cury < cur->y2; cury++)
-           {
-             for(curx = cur->x1; curx < cur->x2; curx++)
-               {
-                 guchar *ptr = mem + (cury * rowstride) + (curx >> 3);
-
-                 if(pixel)
-                   *ptr |= (1 << (curx % 8));
-                 else
-                   *ptr &= ~(1 << (curx % 8));
-               }
-           }
+         {
+           int fromx = MIN((cur->x1+7)&(~7), cur->x2);
+           int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
+           guchar begmask, endmask;
+           int body_end = cur->x2 & ~7;
+           int body_len = (body_end - fromx)/8;
+
+           begmask = ((1 << (begn + begoff)) - 1)
+             & ~((1 << (begoff)) - 1);
+           endn = cur->x2 - body_end;
+           endmask = (1 << endn) - 1;
+
+           for(cury = cur->y1; cury < cur->y2; cury++)
+             {
+               ptr = mem + cury*rowstride + (cur->x1 >> 3);
+
+               if(spot.pixel)
+                 *ptr |= begmask;
+               else
+                 *ptr &= ~begmask;
+
+               curx = fromx;
+
+               if(curx < cur->x2)
+                 {
+                   ptr = mem + cury*rowstride + (curx >> 3);
+                   memset(ptr, spot.pixel?0xFF:0, body_len);
+
+                   if(endn)
+                     {
+                       ptr = mem + cury*rowstride + (body_end >> 3);
+                       if(spot.pixel)
+                         *ptr |= endmask;
+                       else
+                         *ptr &= ~endmask;
+                     }
+                 }
+             }
+         }
          break;
-
        case 8:
          for(cury = cur->y1; cury < cur->y2; cury++)
            {
-             guchar *ptr = mem + (cury * rowstride) + cur->x1;
-             memset(ptr, pixel, cur->x2 - cur->x1);
+             ptr = mem + cury*rowstride + cur->x1;
+             memset(ptr, spot.pixel, cur->x2 - cur->x1);
            }
          break;
-
        case 16:
+         {
+           int i;
+           n = cur->x2 - cur->x1;
+           for(cury = cur->y1; cury < cur->y2; cury++)
+             {
+               guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
+               for(i = 0; i < n; i++)
+                 *(p16++) = spot.pixel;
+             }
+         }
+         break;
        case 24:
+         {
+           guchar redval = spot.red>>8, greenval=spot.green>>8, blueval=spot.blue>>8;
+           guchar *firstline, *ptr_end;
+
+           if((cur->y2 - cur->y1) <= 0)
+             break;
+
+           n = (cur->x2 - cur->x1)*3;
+
+           firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
+           ptr_end = ptr+n;
+           while(ptr < ptr_end)
+             {
+               ptr[gdk_display->red_byte] = redval;
+               ptr[gdk_display->green_byte] = greenval;
+               ptr[gdk_display->blue_byte] = blueval;
+               ptr += 3;
+             }
+           for(cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
+             {
+               memcpy(ptr, firstline, n);
+             }
+         }
+         break;
        case 32:
+         {
+           int i;
+           n = cur->x2 - cur->x1;
+           for(cury = cur->y1; cury < cur->y2; cury++)
+             {
+               guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
+               for(i = 0; i < n; i++)
+                 *(p32++) = spot.pixel;
+             }
+         }
+         break;
+       default:
+         g_assert_not_reached();
+#if 0
          for(cury = cur->y1; cury < cur->y2; cury++)
            {
              for(curx = cur->x1; curx < cur->x2; curx++)
                {
-                 guint *ptr2 = (guint *)(mem + (cury * rowstride) + (curx * (depth >> 3)));
-
-                 *ptr2 = (*ptr2 & ~(visual->red_mask|visual->green_mask|visual->blue_mask)) | pixel;
+                 gdk_fb_drawable_set_pixel(drawable, gc, curx, cury, &spot, TRUE);
                }
            }
+#endif
          break;
        }
     }
@@ -430,7 +454,7 @@ gdk_fb_fill_spans(GdkDrawable *drawable,
                  GdkRectangle *rects, int nrects)
 {
   int i;
-  guint pixel;
+  GdkColor color;
   GdkRegion *real_clip_region, *tmpreg;
   GdkRectangle draw_rect, cursor_rect;
   GdkVisual *visual = gdk_visual_get_system();
@@ -441,12 +465,12 @@ gdk_fb_fill_spans(GdkDrawable *drawable,
   if(GDK_IS_WINDOW(drawable) && GDK_WINDOW_P(drawable)->input_only)
     g_error("Drawing on the evil input-only!");
 
-  if(gc)
-    pixel = GDK_GC_FBDATA(gc)->values.foreground.pixel;
+  if(gc && (GDK_GC_FBDATA(gc)->values_mask | GDK_GC_FOREGROUND))
+    color = GDK_GC_FBDATA(gc)->values.foreground;
   else if(GDK_IS_WINDOW(drawable))
-    pixel = GDK_WINDOW_P(drawable)->bg_color.pixel;
+    color = GDK_WINDOW_P(drawable)->bg_color;
   else
-    pixel = 0;
+    gdk_color_black(GDK_DRAWABLE_P(drawable)->colormap, &color);
 
   real_clip_region = gdk_fb_clip_region(drawable, gc, TRUE);
 
@@ -496,11 +520,14 @@ gdk_fb_fill_spans(GdkDrawable *drawable,
          tmpreg = gdk_region_rectangle(&draw_rect);
          gdk_region_intersect(tmpreg, real_clip_region);
          for(j = 0; j < tmpreg->numRects; j++)
-           gdk_fb_fill_span(drawable, gc, &tmpreg->rects[j], pixel, visual);
+           {
+             cur = tmpreg->rects[j];
+             gdk_fb_fill_span(drawable, gc, &cur, &color, visual);
+           }
          gdk_region_destroy(tmpreg);
          break;
        case GDK_OVERLAP_RECTANGLE_IN:
-         gdk_fb_fill_span(drawable, gc, &cur, pixel, visual);
+         gdk_fb_fill_span(drawable, gc, &cur, &color, visual);
          break;
        default:
          break;
@@ -512,6 +539,230 @@ gdk_fb_fill_spans(GdkDrawable *drawable,
     gdk_fb_cursor_unhide();
 }
 
+typedef enum { GPR_USED_BG, GPR_AA_GRAYVAL, GPR_NONE, GPR_ERR_BOUNDS } GetPixelRet;
+static GetPixelRet
+gdk_fb_drawable_get_pixel(GdkDrawable *drawable, GdkGC *gc, int x, int y, GdkColor *spot,
+                         gboolean abs_coords, GdkDrawable *bg_relto, GdkDrawable *bgpm)
+{
+  GetPixelRet retval = GPR_NONE;
+  guchar *mem = GDK_DRAWABLE_FBDATA(drawable)->mem;
+  guint rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride;
+
+  if(!abs_coords)
+    {
+      x += GDK_DRAWABLE_FBDATA(drawable)->abs_x;
+      y += GDK_DRAWABLE_FBDATA(drawable)->abs_y;
+    }
+
+  switch(GDK_DRAWABLE_P(drawable)->depth)
+    {
+    case 1:
+      {
+       guchar foo = mem[(x >> 3) + y * rowstride];
+       if(foo & (1 << (x % 8)))
+         *spot = GDK_GC_FBDATA(gc)->values.foreground;
+       else
+         {
+           retval = GPR_USED_BG;
+
+           if(bgpm)
+             {
+               int bgx, bgy;
+
+               bgx = (x - GDK_DRAWABLE_FBDATA(bg_relto)->abs_x) % GDK_DRAWABLE_P(bgpm)->width;
+               bgy = (y - GDK_DRAWABLE_FBDATA(bg_relto)->abs_y) % GDK_DRAWABLE_P(bgpm)->height;
+
+               gdk_fb_drawable_get_pixel(bgpm, gc, bgx, bgy, spot, FALSE, NULL, NULL);
+               retval = GPR_USED_BG;
+             }
+           else
+             {
+               *spot = GDK_GC_FBDATA(gc)->values.background;
+             }
+         }
+      }
+      break;
+    case 71:
+      if(mem[x + y * rowstride])
+       *spot = GDK_GC_FBDATA(gc)->values.foreground;
+      else
+       *spot = GDK_GC_FBDATA(gc)->values.background;
+      break;
+    case 77:
+      retval = GPR_AA_GRAYVAL;
+      spot->pixel = mem[x + y * rowstride] << 1;
+      spot->red = spot->green = spot->blue = spot->pixel << 8;
+      break;
+    case 78: /* AA mode */
+      retval = GPR_AA_GRAYVAL;
+      spot->pixel = mem[x + y * rowstride];
+      spot->red = spot->green = spot->blue = spot->pixel << 8;
+      break;
+    case 8:
+      spot->pixel = mem[x + y * rowstride];
+      *spot = GDK_DRAWABLE_P(drawable)->colormap->colors[spot->pixel];
+      break;
+    case 16:
+      {
+       guint16 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
+
+       spot->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
+       spot->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
+       spot->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
+
+       spot->pixel = val16;
+      }
+      break;
+    case 24:
+      {
+       guchar *smem = &mem[x*3 + y*rowstride];
+       spot->red = smem[gdk_display->red_byte] << 8;
+       spot->green = smem[gdk_display->green_byte] << 8;
+       spot->blue = smem[gdk_display->blue_byte] << 8;
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+       spot->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
+#else
+       spot->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
+#endif
+      }
+      break;
+    case 32:
+      {
+       guchar *smem = &mem[x*4 + y*rowstride];
+       spot->red = smem[gdk_display->red_byte] << 8;
+       spot->green = smem[gdk_display->green_byte] << 8;
+       spot->blue = smem[gdk_display->blue_byte] << 8;
+       spot->pixel = *(guint32 *)smem;
+      }
+      break;
+    }
+
+  return retval;
+}
+
+static void
+gdk_fb_drawable_set_pixel(GdkDrawable *drawable, GdkGC *gc, int x, int y, GdkColor *spot,
+                         gboolean abs_coords)
+{
+  guchar *mem = GDK_DRAWABLE_FBDATA(drawable)->mem;
+  guint rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride;
+
+  if(!abs_coords)
+    {
+      x += GDK_DRAWABLE_FBDATA(drawable)->abs_x;
+      y += GDK_DRAWABLE_FBDATA(drawable)->abs_y;
+    }
+
+  switch(GDK_DRAWABLE_P(drawable)->depth)
+    {
+    case 1:
+      {
+       guchar *foo = mem + (y*rowstride) + (x >> 3);
+
+       if(spot->pixel)
+         *foo |= (1 << (x % 8));
+       else
+         *foo &= ~(1 << (x % 8));
+      }
+      break;
+    case 8:
+      mem[x + y*rowstride] = spot->pixel;
+      break;
+    case 16:
+      {
+       guint16 *p16 = (guint16 *)&mem[x*2 + y*rowstride];
+       *p16 = spot->pixel;
+      }
+      break;
+    case 24:
+      {
+       guchar *smem = &mem[x*3 + y*rowstride];
+       smem[gdk_display->red_byte] = spot->red >> 8;
+       smem[gdk_display->green_byte] = spot->green >> 8;
+       smem[gdk_display->blue_byte] = spot->blue >> 8;
+      };
+      break;
+    case 32:
+      {
+       guint32 *smem = (guint32 *)&mem[x*4 + y*rowstride];
+       *smem = spot->pixel;
+      }
+      break;
+    default:
+      g_assert_not_reached();
+      break;
+    }
+
+}
+
+void
+gdk_fb_drawing_context_init(GdkFBDrawingContext *dc,
+                           GdkDrawable *drawable,
+                           GdkGC *gc,
+                           gboolean draw_bg,
+                           gboolean do_clipping)
+{
+  dc->mem = GDK_DRAWABLE_FBDATA(drawable)->mem;
+  dc->rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride;
+  dc->handle_cursor = FALSE;
+  dc->bgpm = NULL;
+  dc->bg_relto = drawable;
+  dc->draw_bg = draw_bg;
+
+  if(GDK_IS_WINDOW(drawable))
+    {
+      dc->bgpm = GDK_WINDOW_P(drawable)->bg_pixmap;
+      if(dc->bgpm == GDK_PARENT_RELATIVE_BG)
+       {
+         for(; dc->bgpm == GDK_PARENT_RELATIVE_BG && dc->bg_relto; dc->bg_relto = GDK_WINDOW_P(dc->bg_relto)->parent)
+           dc->bgpm = GDK_WINDOW_P(dc->bg_relto)->bg_pixmap;
+       }
+
+      if(dc->bgpm == GDK_NO_BG)
+       dc->bgpm = NULL;
+    }
+  dc->clipxoff = - GDK_DRAWABLE_FBDATA(drawable)->abs_x;
+  dc->clipyoff = - GDK_DRAWABLE_FBDATA(drawable)->abs_y;
+
+  dc->real_clip_region = gdk_fb_clip_region(drawable, gc, do_clipping);
+
+  if(gc)
+    {
+      dc->clipxoff -= GDK_GC_FBDATA(gc)->values.clip_x_origin;
+      dc->clipyoff -= GDK_GC_FBDATA(gc)->values.clip_y_origin;
+
+      if(GDK_GC_FBDATA(gc)->values.clip_mask)
+       {
+         dc->clipmem = GDK_DRAWABLE_FBDATA(GDK_GC_FBDATA(gc)->values.clip_mask)->mem;
+         dc->clip_rowstride = GDK_DRAWABLE_FBDATA(GDK_GC_FBDATA(gc)->values.clip_mask)->rowstride;
+       }
+    }
+
+  if(do_clipping)
+    {
+      GdkRectangle cursor_rect;
+
+      gdk_fb_get_cursor_rect(&cursor_rect);
+
+      if(GDK_DRAWABLE_FBDATA(drawable)->mem == GDK_DRAWABLE_FBDATA(gdk_parent_root)->mem
+        && cursor_rect.x >= 0
+        && gdk_region_rect_in(dc->real_clip_region, &cursor_rect) != GDK_OVERLAP_RECTANGLE_OUT)
+       {
+         dc->handle_cursor = TRUE;
+         gdk_fb_cursor_hide();
+       }
+    }
+}
+
+void
+gdk_fb_drawing_context_finalize(GdkFBDrawingContext *dc)
+{
+  gdk_region_destroy(dc->real_clip_region);
+
+  if(dc->handle_cursor)
+    gdk_fb_cursor_unhide();
+}
+
 void
 gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
                        GdkGC       *gc,
@@ -525,57 +776,58 @@ gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
                        gboolean     draw_bg,
                        gboolean     do_clipping)
 {
-  GdkRegion *real_clip_region, *tmpreg;
-  GdkRectangle rect, cursor_rect;
-  int i;
-  int src_x_off, src_y_off;
-  int clipxoff, clipyoff;
-  guchar *mem = GDK_DRAWABLE_FBDATA(drawable)->mem, *srcmem = GDK_DRAWABLE_FBDATA(src)->mem;
-  guchar *clipmem;
-  guint rowstride = GDK_DRAWABLE_FBDATA(drawable)->rowstride, src_rowstride = GDK_DRAWABLE_FBDATA(src)->rowstride;
-  guint clip_rowstride;
-  GdkDrawableFBData *fbd;
-  gboolean handle_cursor = FALSE;
-  GdkPixmap *bgpm = NULL;
-  GdkWindow *bg_relto = drawable;
+  GdkFBDrawingContext *dc, dc_data;
+  dc = &dc_data;
 
-  if(GDK_IS_WINDOW(drawable) && !GDK_WINDOW_P(drawable)->mapped)
-    return;
-  if(GDK_IS_WINDOW(drawable) && GDK_WINDOW_P(drawable)->input_only)
-    g_error("Drawing on the evil input-only!");
+  gdk_fb_drawing_context_init(dc, drawable, gc, draw_bg, do_clipping);
+  gdk_fb_draw_drawable_3(drawable, gc, src, dc, xsrc, ysrc, xdest, ydest, width, height);
+  gdk_fb_drawing_context_finalize(dc);
+}
+
+void
+gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
+                       GdkGC       *gc,
+                       GdkPixmap   *src,
+                       GdkFBDrawingContext *dc,
+                       gint         xsrc,
+                       gint         ysrc,
+                       gint         xdest,
+                       gint         ydest,
+                       gint         width,
+                       gint         height)
+{
+  GdkRectangle rect;
+  guchar *srcmem = GDK_DRAWABLE_FBDATA(src)->mem;
+  int src_x_off, src_y_off;
+  GdkRegion *tmpreg, *real_clip_region;
+  int i;
 
   if(GDK_IS_WINDOW(drawable))
     {
-      bgpm = GDK_WINDOW_P(drawable)->bg_pixmap;
-      if(bgpm == GDK_PARENT_RELATIVE_BG)
-       {
-         for(; bgpm == GDK_PARENT_RELATIVE_BG && bg_relto; bg_relto = GDK_WINDOW_P(bg_relto)->parent)
-           bgpm = GDK_WINDOW_P(bg_relto)->bg_pixmap;
-       }
-
-      if(bgpm == GDK_NO_BG)
-       bgpm = NULL;
-
-      if(bgpm)
-       g_assert(GDK_DRAWABLE_P(bgpm)->depth == 8);
+      if(!GDK_WINDOW_P(drawable)->mapped)
+       return;
+      if(GDK_WINDOW_P(drawable)->input_only)
+       g_error("Drawing on the evil input-only!");
     }
 
   if(drawable == src)
     {
       GdkDrawableFBData *fbd = GDK_DRAWABLE_FBDATA(src);
+
       /* One lame hack deserves another ;-) */
       srcmem = g_alloca(fbd->rowstride * fbd->lim_y);
-      memcpy(srcmem, mem, fbd->rowstride * fbd->lim_y);
+      memcpy(srcmem, dc->mem, fbd->rowstride * fbd->lim_y);
     }
 
-  real_clip_region = gdk_fb_clip_region(drawable, gc, do_clipping);
+  /* Do some magic to avoid creating extra regions unnecessarily */
+  tmpreg = dc->real_clip_region;
+
   rect.x = xdest + GDK_DRAWABLE_FBDATA(drawable)->abs_x;
   rect.y = ydest + GDK_DRAWABLE_FBDATA(drawable)->abs_y;
   rect.width = width;
   rect.height = height;
-  tmpreg = gdk_region_rectangle(&rect);
+  real_clip_region = gdk_region_rectangle(&rect);
   gdk_region_intersect(real_clip_region, tmpreg);
-  gdk_region_destroy(tmpreg);
 
   rect.x = xdest + GDK_DRAWABLE_FBDATA(drawable)->abs_x;
   rect.y = ydest + GDK_DRAWABLE_FBDATA(drawable)->abs_y;
@@ -589,30 +841,6 @@ gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
 
   src_x_off = (GDK_DRAWABLE_FBDATA(src)->abs_x + xsrc) - (GDK_DRAWABLE_FBDATA(drawable)->abs_x + xdest);
   src_y_off = (GDK_DRAWABLE_FBDATA(src)->abs_y + ysrc) - (GDK_DRAWABLE_FBDATA(drawable)->abs_y + ydest);
-  clipxoff = - GDK_DRAWABLE_FBDATA(drawable)->abs_x;
-  clipyoff = - GDK_DRAWABLE_FBDATA(drawable)->abs_y;
-  if(gc)
-    {
-      clipxoff -= GDK_GC_FBDATA(gc)->values.clip_x_origin;
-      clipyoff -= GDK_GC_FBDATA(gc)->values.clip_y_origin;
-
-      if(GDK_GC_FBDATA(gc)->values.clip_mask)
-       {
-         fbd = GDK_DRAWABLE_FBDATA(GDK_GC_FBDATA(gc)->values.clip_mask);
-         clipmem = GDK_DRAWABLE_FBDATA(GDK_GC_FBDATA(gc)->values.clip_mask)->mem;
-         clip_rowstride = GDK_DRAWABLE_FBDATA(GDK_GC_FBDATA(gc)->values.clip_mask)->rowstride;
-       }
-    }
-
-  gdk_fb_get_cursor_rect(&cursor_rect);
-  if(do_clipping
-     && GDK_DRAWABLE_FBDATA(drawable)->mem == GDK_DRAWABLE_FBDATA(gdk_parent_root)->mem
-     && cursor_rect.x >= 0
-     && gdk_region_rect_in(real_clip_region, &cursor_rect) != GDK_OVERLAP_RECTANGLE_OUT)
-    {
-      handle_cursor = TRUE;
-      gdk_fb_cursor_hide();
-    }
 
   for(i = 0; i < real_clip_region->numRects; i++)
     {
@@ -620,16 +848,19 @@ gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
       int cur_y;
 
       if(GDK_DRAWABLE_P(src)->depth == GDK_DRAWABLE_P(drawable)->depth
-        && GDK_DRAWABLE_P(src)->depth > 1
+        && GDK_DRAWABLE_P(src)->depth >= 8
+        && GDK_DRAWABLE_P(src)->depth <= 32
         && (!gc || !GDK_GC_FBDATA(gc)->values.clip_mask))
        {
          guint depth = GDK_DRAWABLE_P(src)->depth;
+         guint src_rowstride = GDK_DRAWABLE_FBDATA(src)->rowstride;
+         int linelen = (cur->x2 - cur->x1)*(depth>>3);
 
          for(cur_y = cur->y1; cur_y < cur->y2; cur_y++)
            {
-             memcpy(mem + (cur_y * rowstride) + cur->x1*(depth>>3),
+             memcpy(dc->mem + (cur_y * dc->rowstride) + cur->x1*(depth>>3),
                     srcmem + ((cur_y + src_y_off)*src_rowstride) + (cur->x1 + src_x_off)*(depth>>3),
-                    (cur->x2 - cur->x1)*(depth>>3));
+                    linelen);
            }
        }
       else
@@ -640,96 +871,118 @@ gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
            {
              for(cur_x = cur->x1; cur_x < cur->x2; cur_x++)
                {
-                 guint pixel;
-                 guint16 *p16;
-                 guint32 *p32;
+                 GdkColor spot;
 
                  if(gc && GDK_GC_FBDATA(gc)->values.clip_mask)
                    {
-                     int maskx = cur_x+clipxoff, masky = cur_y + clipyoff;
+                     int maskx = cur_x+dc->clipxoff, masky = cur_y + dc->clipyoff;
                      guchar foo;
 
-                     if(maskx < 0 || masky < 0)
-                       continue;
-
-                     foo = clipmem[masky*clip_rowstride + (maskx >> 3)];
+                     foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
 
                      if(!(foo & (1 << (maskx % 8))))
                        continue;
                    }
 
-                 switch(GDK_DRAWABLE_P(src)->depth)
-                   {
-                   case 1:
-                     {
-                       guchar foo = srcmem[((cur_x + src_x_off) >> 3) + ((cur_y + src_y_off)*src_rowstride)];
-
-                       if(foo & (1 << ((cur_x + src_x_off) % 8))) {
-                         pixel = GDK_GC_FBDATA(gc)->values.foreground.pixel;
-                       } else if(draw_bg) {
-                         if(bgpm)
-                           {
-                             int bgx, bgy;
-
-                             bgx = (cur_x - GDK_DRAWABLE_FBDATA(bg_relto)->abs_x) % GDK_DRAWABLE_P(bgpm)->width;
-                             bgy = (cur_y - GDK_DRAWABLE_FBDATA(bg_relto)->abs_y) % GDK_DRAWABLE_P(bgpm)->height;
-
-                             pixel = GDK_DRAWABLE_FBDATA(bgpm)->mem[bgx + bgy * GDK_DRAWABLE_FBDATA(bgpm)->rowstride];
-                           }
-                         else
-                           pixel = GDK_GC_FBDATA(gc)->values.background.pixel;
-                       } else
-                         continue;
-                     }
-                     break;
-                   case 8:
-                     pixel = srcmem[(cur_x + src_x_off) + ((cur_y + src_y_off)*src_rowstride)];
-                     break;
-                   case 16:
-                     pixel = *(guint16 *)(srcmem + (cur_x + src_x_off)*2 + ((cur_y + src_y_off)*src_rowstride));
-                     break;
-                   case 24:
-                     pixel = 0x00FFFFFF & *(guint32 *)(srcmem + (cur_x + src_x_off)*3 + ((cur_y + src_y_off)*src_rowstride));
-                     break;
-                   case 32:
-                     pixel = *(guint32 *)(srcmem + (cur_x + src_x_off)*4 + ((cur_y + src_y_off)*src_rowstride));
-                     break;
-                   default:
-                     g_assert_not_reached();
-                     break;
-                   }
-
-                 switch(GDK_DRAWABLE_P(drawable)->depth)
+                 switch(gdk_fb_drawable_get_pixel(src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot, TRUE, NULL, NULL))
                    {
-                   case 1:
+                   case GPR_AA_GRAYVAL:
                      {
-                       guchar *foo = mem + (cur_y*src_rowstride) + (cur_x >> 3);
-
-                       if(pixel == GDK_GC_FBDATA(gc)->values.foreground.pixel)
-                         *foo |= (1 << (cur_x % 8));
+                       GdkColor realspot, fg;
+                       guint graylevel = spot.pixel;
+                       gint tmp;
+
+                       if(GDK_DRAWABLE_P(drawable)->depth == 1)
+                         {
+                           if(spot.pixel > 192)
+                             spot = GDK_GC_FBDATA(gc)->values.foreground;
+                           else
+                            spot = GDK_GC_FBDATA(gc)->values.background;
+                           break;
+                         }
                        else
-                         *foo &= ~(1 << (cur_x % 8));
+                         {
+                           if(graylevel >= 254)
+                             {
+                               spot = GDK_GC_FBDATA(gc)->values.foreground;
+                             }
+                           else if(graylevel <= 2)
+                             {
+                               if(!dc->draw_bg)
+                                 continue;
+
+                               spot = GDK_GC_FBDATA(gc)->values.background;
+                             }
+                           else
+                             {
+                               switch(gdk_fb_drawable_get_pixel(drawable, gc, cur_x, cur_y, &realspot, TRUE, dc->bg_relto, dc->bgpm))
+                                 {
+                                 case GPR_NONE:
+                                 case GPR_USED_BG:
+                                   break;
+                                 default:
+                                   g_assert_not_reached();
+                                   break;
+                                 }
+
+                               fg = GDK_GC_FBDATA(gc)->values.foreground;
+                               /* Now figure out what 'spot' should actually look like */
+                               fg.red >>= 8;
+                               fg.green >>= 8;
+                               fg.blue >>= 8;
+                               realspot.red >>= 8;
+                               realspot.green >>= 8;
+                               realspot.blue >>= 8;
+
+                               tmp = (fg.red - realspot.red) * graylevel;
+                               spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                               spot.red <<= 8;
+
+                               tmp = (fg.green - realspot.green) * graylevel;
+                               spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                               spot.green <<= 8;
+
+                               tmp = (fg.blue - realspot.blue) * graylevel;
+                               spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                               spot.blue <<= 8;
+
+                               /* Now find the pixel for this thingie */
+                               switch(GDK_DRAWABLE_P(drawable)->depth)
+                                 {
+                                 case 8:
+                                   if(!gdk_colormap_alloc_color(GDK_DRAWABLE_P(drawable)->colormap, &spot, FALSE, TRUE))
+                                     {
+                                       g_error("Can't allocate AA color!");
+                                     }
+                                   break;
+                                 case 16:
+                                   spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
+                                   spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
+                                   spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
+                                   break;
+                                 case 24:
+                                 case 32:
+                                   spot.pixel = ((spot.red & 0xFF00) << (gdk_display->modeinfo.red.offset - 8))
+                                     | ((spot.green & 0xFF00) << (gdk_display->modeinfo.green.offset - 8))
+                                     | ((spot.blue & 0xFF00) << (gdk_display->modeinfo.blue.offset - 8));
+                                   break;
+                                 }
+                             }
+                         }
                      }
                      break;
-                   case 8:
-                     mem[cur_x + cur_y*rowstride] = pixel;
-                     break;
-                   case 16:
-                     p16 = (guint16 *)&mem[cur_x*2 + cur_y*rowstride];
-                     *p16 = pixel;
-                     break;
-                   case 24:
-                     p32 = (guint32 *)&mem[cur_x*3 + cur_y*rowstride];
-                     *p32 = (*p32 & 0xFF000000) | pixel;
+                   case GPR_USED_BG:
+                     if(!dc->draw_bg)
+                       continue;
                      break;
-                   case 32:
-                     p32 = (guint32 *)&mem[cur_x*4 + cur_y*rowstride];
-                     *p32 = pixel;
+                   case GPR_NONE:
                      break;
                    default:
                      g_assert_not_reached();
                      break;
                    }
+
+                 gdk_fb_drawable_set_pixel(drawable, gc, cur_x, cur_y, &spot, GDK_DRAWABLE_P(src)->depth);
                }
            }
        }
@@ -737,9 +990,6 @@ gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
 
  out:
   gdk_region_destroy(real_clip_region);
-
-  if(handle_cursor)
-    gdk_fb_cursor_unhide();
 }
 
 void
@@ -765,33 +1015,7 @@ gdk_fb_draw_text(GdkDrawable    *drawable,
                 const gchar    *text,
                 gint            text_length)
 {
-  GLYPH *g;
-  GdkDrawablePrivate tmp_pixmap;
-  GdkDrawableFBData fbd;
-
-  if(GDK_IS_WINDOW(drawable) && !GDK_WINDOW_P(drawable)->mapped)
-    return;
-
-  y -= font->ascent; /* y is relative to baseline, we want it relative to top left corner */
-
-  g = T1_SetString(GDK_FONT_FB(font)->t1_font_id, (char *)text, text_length, 0, T1_KERNING, GDK_FONT_FB(font)->size,
-                  NULL);
-  g_assert(g);
-
-  tmp_pixmap.window_type = GDK_DRAWABLE_PIXMAP;
-  tmp_pixmap.width = (g->metrics.rightSideBearing - g->metrics.leftSideBearing);
-  tmp_pixmap.height = (g->metrics.ascent - g->metrics.descent);
-  tmp_pixmap.depth = 1;
-
-  fbd.mem = g->bits;
-  fbd.abs_x = fbd.abs_y = fbd.llim_x = fbd.llim_y = 0;
-  fbd.lim_x = tmp_pixmap.width;
-  fbd.lim_y = tmp_pixmap.height;
-  fbd.rowstride = (tmp_pixmap.width + 7) / 8;
-  tmp_pixmap.klass_data = &fbd;
-  tmp_pixmap.klass = &_gdk_fb_drawable_class;
-
-  gdk_fb_draw_drawable_2(drawable, gc, (GdkPixmap *)&tmp_pixmap, 0, 0, x, y, tmp_pixmap.width, tmp_pixmap.height, FALSE, TRUE);
+  g_warning("gdk_fb_draw_text NYI");
 }
 
 static void
@@ -803,19 +1027,7 @@ gdk_fb_draw_text_wc (GdkDrawable    *drawable,
                     const GdkWChar *text,
                     gint             text_length)
 {
-  char *realbuf;
-  int i;
-
-  if(GDK_IS_WINDOW(drawable) && (!GDK_WINDOW_P(drawable)->mapped || GDK_WINDOW_P(drawable)->input_only))
-    return;
-
-  /* A hack, a hack, a pretty little hack */
-  realbuf = alloca(text_length + 1);
-  for(i = 0; i < text_length; i++)
-    realbuf[i] = text[i];
-  realbuf[i] = 0;
-
-  gdk_fb_draw_text(drawable, font, gc, x, y, realbuf, text_length);
+  g_warning("gdk_fb_draw_text_wc NYI");
 }
 
 void
@@ -831,17 +1043,6 @@ gdk_fb_draw_rectangle (GdkDrawable    *drawable,
 
   if(filled)
     {
-#if 0
-      static volatile int print_rect = 0;
-
-      if(print_rect)
-       {
-         fprintf(debug_out, "[%d, %d] +[%d, %d]\n", x, y, width, height);
-         if(y < 0)
-           G_BREAKPOINT();
-       }
-#endif
-
       rect.x = x;
       rect.y = y;
       rect.width = width;
@@ -868,7 +1069,7 @@ static void gdk_fb_draw_points    (GdkDrawable    *drawable,
                                   GdkPoint       *points,
                                   gint            npoints)
 {
-  GdkRectangle *rects = alloca(npoints * sizeof(GdkRectangle));
+  GdkRectangle *rects = g_alloca(npoints * sizeof(GdkRectangle));
   int i;
 
   for(i = 0; i < npoints; i++)
@@ -916,7 +1117,7 @@ static void gdk_fb_draw_polygon   (GdkDrawable    *drawable,
     miFillPolygon(drawable, gc, 0, 0, npoints, points);
   else
     {
-      GdkPoint *realpts = alloca(sizeof(GdkPoint) * (npoints + 1));
+      GdkPoint *realpts = g_alloca(sizeof(GdkPoint) * (npoints + 1));
 
       memcpy(realpts, points, sizeof(GdkPoint) * npoints);
       realpts[npoints] = points[0];
@@ -957,5 +1158,112 @@ static void gdk_fb_draw_segments  (GdkDrawable    *drawable,
 void
 gdk_fb_drawable_clear(GdkDrawable *d)
 {
+  extern void
+    _gdk_windowing_window_clear_area (GdkWindow *window,
+                                     gint       x,
+                                     gint       y,
+                                     gint       width,
+                                     gint       height);
+
   _gdk_windowing_window_clear_area(d, 0, 0, GDK_DRAWABLE_P(d)->width, GDK_DRAWABLE_P(d)->height);
 }
+
+extern FT_Library gdk_fb_ft_lib;
+
+extern void pango_fb_font_set_size(PangoFont *font);
+
+static void gdk_fb_draw_glyphs(GdkDrawable      *drawable,
+                              GdkGC            *gc,
+                              PangoFont        *font,
+                              gint              x,
+                              gint              y,
+                              PangoGlyphString *glyphs)
+{
+  int i;
+  GdkPixmapFBData fbd;
+  GdkDrawablePrivate tmp_foo;
+  FT_Face ftf;
+  int xpos;
+  GdkFBDrawingContext fbdc;
+
+  g_return_if_fail(font);
+
+  gdk_fb_drawing_context_init(&fbdc, drawable, gc, FALSE, TRUE);
+
+  ftf = PANGO_FB_FONT(font)->ftf;
+
+  /* Fake its existence as a pixmap */
+  memset(&tmp_foo, 0, sizeof(tmp_foo));
+  memset(&fbd, 0, sizeof(fbd));
+  tmp_foo.klass = &_gdk_fb_drawable_class;
+  tmp_foo.klass_data = &fbd;
+  tmp_foo.window_type = GDK_DRAWABLE_PIXMAP;
+
+  pango_fb_font_set_size(font);
+  for(i = xpos = 0; i < glyphs->num_glyphs; i++)
+    {
+      FT_GlyphSlot g;
+      FT_Bitmap *renderme;
+      int this_wid;
+
+      FT_Load_Glyph(ftf, glyphs->glyphs[i].glyph, FT_LOAD_DEFAULT);
+      g = ftf->glyph;
+
+      if(g->format != ft_glyph_format_bitmap)
+       {
+         FT_BitmapGlyph bgy;
+         int bdepth;
+#ifdef USE_AA
+#ifdef USE_FTGRAYS
+         bdepth = 256;
+#else
+         bdepth = 128;
+#endif
+#else
+         bdepth = 0;
+#endif
+
+         if(FT_Get_Glyph_Bitmap(ftf, glyphs->glyphs[i].glyph, 0, bdepth, NULL, &bgy))
+           continue;
+
+         renderme = &bgy->bitmap;
+       }
+      else
+       renderme = &g->bitmap;
+
+      fbd.drawable_data.mem = renderme->buffer;
+      fbd.drawable_data.rowstride = renderme->pitch;
+      tmp_foo.width = fbd.drawable_data.lim_x = renderme->width;
+      tmp_foo.height = fbd.drawable_data.lim_y = renderme->rows;
+
+      switch(renderme->pixel_mode)
+       {
+       case ft_pixel_mode_mono:
+         tmp_foo.depth = 1;
+         break;
+       case ft_pixel_mode_grays:
+#if defined(USE_FTGRAYS)
+         tmp_foo.depth = 78;
+#else
+         tmp_foo.depth = 77;
+#endif
+         break;
+       default:
+         g_assert_not_reached();
+         break;
+       }
+
+      this_wid = (xpos + glyphs->glyphs[i].geometry.width)/PANGO_SCALE;
+      gdk_fb_draw_drawable_3(drawable, gc, (GdkDrawable *)&tmp_foo,
+                            &fbdc,
+                            0, 0,
+                            x + (xpos + glyphs->glyphs[i].geometry.x_offset)/PANGO_SCALE,
+                            y + glyphs->glyphs[i].geometry.y_offset / PANGO_SCALE
+                            + ((-ftf->glyph->metrics.horiBearingY) >> 6),
+                            this_wid, renderme->rows);
+
+      xpos += glyphs->glyphs[i].geometry.width;
+    }
+
+  gdk_fb_drawing_context_finalize(&fbdc);
+}
index 7b80aa364ae3f440f320bdc055eaa67f7f59adfc..f353dc3c39be261b1fb4484e64f4a1d871f77415 100644 (file)
@@ -90,10 +90,27 @@ static GSourceFuncs event_funcs = {
  * Functions for maintaining the event queue *
  *********************************************/
 
+static gboolean fb_events_prepare(gpointer  source_data, 
+                                 GTimeVal *current_time,
+                                 gint     *timeout,
+                                 gpointer  user_data);
+static gboolean fb_events_check(gpointer  source_data,
+                               GTimeVal *current_time,
+                               gpointer  user_data);
+static gboolean fb_events_dispatch(gpointer  source_data, 
+                                  GTimeVal *dispatch_time,
+                                  gpointer  user_data);
 void 
 gdk_events_init (void)
 {
-  
+  static GSourceFuncs fb_events_funcs = {
+    fb_events_prepare,
+    fb_events_check,
+    fb_events_dispatch,
+    NULL
+  };
+
+  g_source_add(G_PRIORITY_HIGH_IDLE, TRUE, &fb_events_funcs, NULL, NULL, NULL);
 }
 
 /*
@@ -121,21 +138,64 @@ gdk_events_pending (void)
 GdkEvent*
 gdk_event_get_graphics_expose (GdkWindow *window)
 {
+  GList *ltmp;
   g_return_val_if_fail (window != NULL, NULL);
   
-  return NULL; 
+  for(ltmp = gdk_queued_events; ltmp; ltmp = ltmp->next)
+    {
+      GdkEvent *event = ltmp->data;
+      if(event->type == GDK_EXPOSE
+        && event->expose.window == window)
+       break;
+    }
+
+  if(ltmp)
+    {
+      GdkEvent *retval = ltmp->data;
+
+      gdk_event_queue_remove_link(ltmp);
+      g_list_free_1(ltmp);
+
+      return retval;
+    }
+
+  return NULL;
 }
 
 void
 gdk_events_queue (void)
+{  
+}
+
+static gboolean
+fb_events_prepare(gpointer  source_data, 
+                 GTimeVal *current_time,
+                 gint     *timeout,
+                 gpointer  user_data)
 {
-  
+  *timeout = -1;
+
+  return fb_events_check(source_data, current_time, user_data);
 }
 
-static gint handler_tag = 0;
+static gboolean
+fb_events_check(gpointer  source_data,
+               GTimeVal *current_time,
+               gpointer  user_data)
+{
+  gboolean retval;
+
+  GDK_THREADS_ENTER();
+
+  retval = (gdk_event_queue_find_first () != NULL);
+
+  GDK_THREADS_LEAVE();
+
+  return retval;
+}
 
 static gboolean
-dispatch_events(gpointer data)
+fb_events_dispatch(gpointer source_data, GTimeVal *dispatch_time, gpointer user_data)
 {
   GdkEvent *event;
 
@@ -148,31 +208,13 @@ dispatch_events(gpointer data)
        gdk_fb_drawable_clear(event->expose.window);
       else if(gdk_event_func)
        (*gdk_event_func)(event, gdk_event_data);
+
       gdk_event_free(event);
     }
 
   GDK_THREADS_LEAVE();
-  if(event && !handler_tag)
-    handler_tag = g_idle_add_full(G_PRIORITY_HIGH_IDLE, dispatch_events, NULL, NULL);
-  else if(!event && handler_tag)
-    {
-      g_source_remove(handler_tag);
-      handler_tag = 0;
-    }
-
-  return handler_tag?TRUE:FALSE;
-}
 
-void
-_gdk_event_queue_changed(GList *queue)
-{
-  if(queue && !handler_tag)
-    handler_tag = g_idle_add_full(G_PRIORITY_HIGH_IDLE, dispatch_events, NULL, NULL);
-  else if(!queue && handler_tag)
-    {
-      g_source_remove(handler_tag);
-      handler_tag = 0;
-    }
+  return TRUE;
 }
 
 /*
index 7cb6f6d3adc6c39bbcac158cb5cb7be9d0c71883..93608ff917dca2b08b5d9451ee5aaab7015b5bd3 100644 (file)
@@ -15,4 +15,9 @@ extern GdkFBDisplay *gdk_display;
 
 extern const char *gdk_progclass;
 
+#define gdk_window_lookup(xid)    (xid)
+#define gdk_pixmap_lookup(xid)    (xid)
+#define gdk_font_lookup(xid)      (xid)
+#define gdk_window_foreign_new(xid) gdk_window_ref(xid)
+
 #endif /* GDKFB_H */
index c22b8401771da358fc9c049b0fd9ce85dcdcf895..e0c554b6e70eab494e12142b646dc8d89c65528b 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include <t1lib.h>
 #include <math.h>
 #include <stdlib.h>
 #include "gdkfont.h"
 #include "gdkprivate-fb.h"
+#include "gdkpango.h"
 
+#include <pango/pango.h>
+
+#include <freetype/freetype.h>
+#if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
+#error "We need Freetype 2.0 (beta?)"
+#endif
+
+GdkFont*
+gdk_font_from_description (PangoFontDescription *font_desc)
+{
+  GdkFont *font;
+  GdkFontPrivateFB *private;
+
+  g_return_val_if_fail(font_desc, NULL);
+
+  private = g_new0(GdkFontPrivateFB, 1);
+  font = (GdkFont *)private;
+  private->base.ref_count = 1;
+
+  return font;
+}
+
+/* ********************* */
+#if 0
 static GHashTable *font_name_hash = NULL;
 static GHashTable *fontset_name_hash = NULL;
 
@@ -139,11 +163,14 @@ gdk_fontset_load (const gchar *fontset_name)
 {
   return gdk_font_load(fontset_name);
 }
+#endif
 
 void
 _gdk_font_destroy (GdkFont *font)
 {
+#if 0
   gdk_font_hash_remove (font->type, font);
+#endif
       
   switch (font->type)
     {
@@ -221,9 +248,11 @@ gdk_font_equal (const GdkFont *fonta,
 
   if(fonta == fontb)
     return TRUE;
+#if 0
   if(privatea->t1_font_id == privateb->t1_font_id
      && privatea->size == privateb->size)
     return TRUE;
+#endif
 
   return FALSE;
 }
@@ -233,6 +262,7 @@ gdk_text_width (GdkFont      *font,
                const gchar  *text,
                gint          text_length)
 {
+#if 0
   GdkFontPrivateFB *private;
   gint width;
   double n;
@@ -256,6 +286,9 @@ gdk_text_width (GdkFont      *font,
     }
 
   return width;
+#else
+  return 0;
+#endif
 }
 
 gint
@@ -263,6 +296,7 @@ gdk_text_width_wc (GdkFont    *font,
                   const GdkWChar *text,
                   gint            text_length)
 {
+#if 0
   char *realstr;
   int i;
 
@@ -272,6 +306,9 @@ gdk_text_width_wc (GdkFont    *font,
   realstr[i] = '\0';
 
   return gdk_text_width(font, realstr, text_length);
+#else
+  return 0;
+#endif
 }
 
 void
@@ -284,6 +321,7 @@ gdk_text_extents (GdkFont     *font,
                  gint        *ascent,
                  gint        *descent)
 {
+#if 0
   GdkFontPrivateFB *private;
   METRICSINFO mi;
 
@@ -304,6 +342,18 @@ gdk_text_extents (GdkFont     *font,
     *lbearing = ((double)mi.bbox.llx) / 1000.0 * private->size;
   if(rbearing)
     *rbearing = ((double)mi.bbox.urx) / 1000.0 * private->size;
+#else
+  if(ascent)
+    *ascent = 0;
+  if(descent)
+    *descent = 0;
+  if(width)
+    *width = 0;
+  if(lbearing)
+    *lbearing = 0;
+  if(rbearing)
+    *rbearing = 0;
+#endif
 }
 
 void
index 02bf5d0591a76c5df406042a918245153da953ba..0d7287bff9bb14caa047e08a1c3ef4d3dd598f78 100644 (file)
@@ -110,7 +110,7 @@ gdk_fb_gc_set_values (GdkGC           *gc,
     {
       oldpm = GDK_GC_FBDATA(gc)->values.tile;
       if(values->tile)
-       g_assert(GDK_DRAWABLE_P(values->tile)->depth == 8);
+       g_assert(GDK_DRAWABLE_P(values->tile)->depth >= 8);
 
       GDK_GC_FBDATA(gc)->values.tile = values->tile?gdk_pixmap_ref(values->tile):NULL;
       GDK_GC_FBDATA(gc)->values_mask |= GDK_GC_TILE;
@@ -137,6 +137,12 @@ gdk_fb_gc_set_values (GdkGC           *gc,
       GDK_GC_FBDATA(gc)->values_mask |= GDK_GC_CLIP_MASK;
       if(oldpm)
        gdk_pixmap_unref(oldpm);
+
+      if(GDK_GC_FBDATA(gc)->clip_region)
+       {
+         gdk_region_destroy(GDK_GC_FBDATA(gc)->clip_region);
+         GDK_GC_FBDATA(gc)->clip_region = NULL;
+       }
     }
 
   if(values_mask & GDK_GC_SUBWINDOW)
@@ -220,6 +226,19 @@ gdk_fb_gc_set_dashes (GdkGC *gc,
     }
 }
 
+static void
+gc_unset_cmask(GdkGC *gc)
+{
+  GdkGCPrivate *private = (GdkGCPrivate *)gc;
+  GdkGCFBData *data;
+  data = GDK_GC_FBDATA (gc);
+  if(data->values.clip_mask)
+    {
+      gdk_pixmap_unref(data->values.clip_mask);
+      data->values.clip_mask = NULL;
+      data->values_mask &= ~ GDK_GC_CLIP_MASK;
+    }
+}
 void
 gdk_gc_set_clip_rectangle (GdkGC       *gc,
                           GdkRectangle *rectangle)
@@ -244,6 +263,8 @@ gdk_gc_set_clip_rectangle (GdkGC    *gc,
   private->clip_y_origin = 0;
   data->values.clip_x_origin = 0;
   data->values.clip_y_origin = 0;
+
+  gc_unset_cmask(gc);
 } 
 
 void
@@ -273,6 +294,8 @@ gdk_gc_set_clip_region (GdkGC         *gc,
   private->clip_y_origin = 0;
   data->values.clip_x_origin = 0;
   data->values.clip_y_origin = 0;
+
+  gc_unset_cmask(gc);
 }
 
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7605bf42212fc5274ecd2bb49356015792cf8eb4 100644 (file)
@@ -0,0 +1,49 @@
+#include "gdkprivate-fb.h"
+
+void
+gdk_window_scroll (GdkWindow *window,
+                   gint       dx,
+                   gint       dy)
+{
+  GdkWindowPrivate *private = GDK_WINDOW_P(window);
+  GdkRegion *invalidate_region;
+  GdkRectangle dest_rect;
+  GdkRectangle clip_rect;
+  GList *tmp_list;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_DRAWABLE_DESTROYED (window))
+    return;
+
+  clip_rect.x = GDK_DRAWABLE_FBDATA(window)->llim_x - GDK_DRAWABLE_FBDATA(window)->abs_x;
+  clip_rect.y = GDK_DRAWABLE_FBDATA(window)->llim_y - GDK_DRAWABLE_FBDATA(window)->abs_y;
+  clip_rect.width = GDK_DRAWABLE_FBDATA(window)->lim_x - GDK_DRAWABLE_FBDATA(window)->llim_x;
+  clip_rect.height = GDK_DRAWABLE_FBDATA(window)->lim_y - GDK_DRAWABLE_FBDATA(window)->llim_y;
+  invalidate_region = gdk_region_rectangle (&clip_rect);
+      
+  dest_rect = clip_rect;
+  dest_rect.x += dx;
+  dest_rect.y += dy;
+  gdk_rectangle_intersect (&dest_rect, &clip_rect, &dest_rect);
+
+  if (dest_rect.width > 0 && dest_rect.height > 0)
+    {
+      GdkRegion *tmp_region;
+
+      tmp_region = gdk_region_rectangle (&dest_rect);
+      gdk_region_subtract (invalidate_region, tmp_region);
+      gdk_region_destroy (tmp_region);
+         
+      gdk_fb_draw_drawable_2(window, NULL, window, dest_rect.x - dx, dest_rect.y - dy, dest_rect.x, dest_rect.y,
+                            dest_rect.width, dest_rect.height,
+                            FALSE, FALSE);
+    }
+
+  gdk_window_invalidate_region (window, invalidate_region, TRUE);
+  gdk_region_destroy (invalidate_region);
+
+  for(tmp_list = private->children; tmp_list; tmp_list = tmp_list->next)
+    gdk_window_move (tmp_list->data, GDK_WINDOW_P(tmp_list->data)->x + dx, GDK_WINDOW_P(tmp_list->data)->y + dy);
+}
index d47f287d33062e74e14d3fcdd7e73cb45f105e59..9b5c73a6a6ff231912b11cf38cbc7756abb3f5fb 100644 (file)
 
 #include <config.h>
 
+#include <endian.h>
+#ifndef __BYTE_ORDER
+#error "endian.h needs to #define __BYTE_ORDER"
+#endif
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -111,7 +115,7 @@ gdk_image_new (GdkImageType  type,
     {
       image->byte_order = 0;
       image->mem = g_malloc(width * height * (image->depth >> 3));
-      image->bpp = image->depth;
+      image->bpp = image->depth/8;
       image->bpl = (width * image->depth + 7)/8;
     }
 
@@ -128,7 +132,7 @@ gdk_image_get (GdkWindow *window,
   GdkImage *image;
   GdkImagePrivateFB *private;
   gint bits_per_pixel = GDK_DRAWABLE_P(gdk_parent_root)->depth;
-  GdkDrawableFBData fbd;
+  GdkPixmapFBData fbd;
   GdkDrawablePrivate tmp_foo;
 
   g_return_val_if_fail (window != NULL, NULL);
@@ -157,7 +161,7 @@ gdk_image_get (GdkWindow *window,
   else
     image->bpp = 4;
   image->byte_order = 1;
-  image->bpl = (image->width * image->bpp + 7)/8;
+  image->bpl = (image->width * image->depth + 7)/8;
   image->mem = g_malloc(image->bpl * image->height);
   
   /* Fake its existence as a pixmap */
@@ -165,11 +169,12 @@ gdk_image_get (GdkWindow *window,
   memset(&fbd, 0, sizeof(fbd));
   tmp_foo.klass = &_gdk_fb_drawable_class;
   tmp_foo.klass_data = &fbd;
-  fbd.mem = image->mem;
-  fbd.rowstride = image->bpl;
-  tmp_foo.width = fbd.lim_x = image->width;
-  tmp_foo.height = fbd.lim_y = image->height;
+  fbd.drawable_data.mem = image->mem;
+  fbd.drawable_data.rowstride = image->bpl;
+  tmp_foo.width = fbd.drawable_data.lim_x = image->width;
+  tmp_foo.height = fbd.drawable_data.lim_y = image->height;
   tmp_foo.depth = image->depth;
+  tmp_foo.window_type = GDK_DRAWABLE_PIXMAP;
 
   gdk_fb_draw_drawable((GdkPixmap *)&tmp_foo, NULL, window, x, y, 0, 0, width, height);
 
@@ -187,9 +192,24 @@ gdk_image_get_pixel (GdkImage *image,
 
   private = (GdkImagePrivateFB *) image;
 
-  g_assert(image->depth == 8);
+  switch(image->depth)
+    {
+    case 8:
+      return ((guchar *)image->mem)[x + y * image->bpl];
+      break;
+    case 16:
+      return *((guint16 *)&((guchar *)image->mem)[x*2 + y*image->bpl]);
+      break;
+    case 24:
+    case 32:
+      {
+       guchar *smem = &(((guchar *)image->mem)[x*image->bpp + y*image->bpl]);
+       return smem[0]|(smem[1]<<8)|(smem[2]<<16);
+      }
+      break;
+    }
 
-  return ((guchar *)image->mem)[x + y * image->bpl];
+  return 0;
 }
 
 void
@@ -198,14 +218,39 @@ gdk_image_put_pixel (GdkImage *image,
                     gint y,
                     guint32 pixel)
 {
-  GdkImagePrivateFB *private;
+  guchar *ptr = image->mem;
 
   g_return_if_fail (image != NULL);
 
-  private = (GdkImagePrivateFB *) image;
-  g_assert(image->depth == 8);
-
-  ((guchar *)image->mem)[x + y * image->bpl] = pixel;
+  switch(image->depth)
+    {
+    case 8:
+      ptr[x + y * image->bpl] = pixel;
+      break;
+    case 16:
+      {
+       guint16 *p16 = (guint16 *)&ptr[x*2 + y*image->bpl];
+       *p16 = pixel;
+      }
+      break;
+    case 24:
+      {
+       guchar *smem = &ptr[x*3 + y*image->bpl];
+       smem[0] = (pixel & 0xFF);
+       smem[1] = (pixel & 0xFF00) >> 8;
+       smem[2] = (pixel & 0xFF0000) >> 16;
+      }
+      break;
+    case 32:
+      {
+       guint32 *smem = (guint32 *)&ptr[x*4 + y*image->bpl];
+       *smem = pixel;
+      }
+      break;
+    default:
+      g_assert_not_reached();
+      break;
+    }
 }
 
 static void
@@ -234,7 +279,7 @@ gdk_image_put_normal (GdkImage    *image,
                      gint         height)
 {
   GdkImagePrivateFB *image_private;
-  GdkDrawableFBData fbd;
+  GdkPixmapFBData fbd;
   GdkDrawablePrivate tmp_foo;
 
   g_return_if_fail (drawable != NULL);
@@ -253,11 +298,12 @@ gdk_image_put_normal (GdkImage    *image,
   memset(&fbd, 0, sizeof(fbd));
   tmp_foo.klass = &_gdk_fb_drawable_class;
   tmp_foo.klass_data = &fbd;
-  fbd.mem = image->mem;
-  fbd.rowstride = image->bpl;
-  tmp_foo.width = fbd.lim_x = image->width;
-  tmp_foo.height = fbd.lim_y = image->height;
+  fbd.drawable_data.mem = image->mem;
+  fbd.drawable_data.rowstride = image->bpl;
+  tmp_foo.width = fbd.drawable_data.lim_x = image->width;
+  tmp_foo.height = fbd.drawable_data.lim_y = image->height;
   tmp_foo.depth = image->depth;
+  tmp_foo.window_type = GDK_DRAWABLE_PIXMAP;
 
   gdk_fb_draw_drawable(drawable, gc, (GdkPixmap *)&tmp_foo, xsrc, ysrc, xdest, ydest, width, height);
 }
index 0db74567287cb8ae2111c62bc7ff3b3fc8f14eca..3631acf7c6c9aea4b4ca37113bd832504c5266e9 100644 (file)
@@ -208,20 +208,43 @@ send_button_event(PS2Mouse *mouse, guint button, gboolean press_event, time_t th
 }
 
 static GdkPixmap *last_contents = NULL;
-static GdkPoint last_location;
+static GdkPoint last_location, last_contents_size;
 static GdkCursor *last_cursor = NULL;
+GdkFBDrawingContext *gdk_fb_cursor_dc = NULL;
+static GdkFBDrawingContext cursor_dc_dat;
 static GdkGC *cursor_gc;
 
+static GdkFBDrawingContext *
+gdk_fb_cursor_dc_reset(void)
+{
+  if(gdk_fb_cursor_dc)
+    gdk_fb_drawing_context_finalize(gdk_fb_cursor_dc);
+
+  gdk_fb_cursor_dc = &cursor_dc_dat;
+  gdk_fb_drawing_context_init(gdk_fb_cursor_dc, gdk_parent_root, cursor_gc, TRUE, FALSE);
+
+  return gdk_fb_cursor_dc;
+}
+
 void
 gdk_fb_cursor_hide(void)
 {
+  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+
+  if(!mydc)
+    mydc = gdk_fb_cursor_dc_reset();
+
   if(last_contents)
     {
       gdk_gc_set_clip_mask(cursor_gc, NULL);
       /* Restore old picture */
-      gdk_fb_draw_drawable_2(gdk_parent_root, cursor_gc, last_contents, 0, 0, last_location.x, last_location.y,
-                            GDK_DRAWABLE_P(last_contents)->width,
-                            GDK_DRAWABLE_P(last_contents)->height, TRUE, FALSE);
+      gdk_fb_draw_drawable_3(gdk_parent_root, cursor_gc, last_contents,
+                            mydc,
+                            0, 0,
+                            last_location.x,
+                            last_location.y,
+                            last_contents_size.x,
+                            last_contents_size.y);
     }
 }
 
@@ -233,13 +256,18 @@ gdk_fb_cursor_invalidate(void)
 }
 
 void
-gdk_fb_cursor_unhide(void)
+gdk_fb_cursor_unhide()
 {
+  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+
+  if(!mydc)
+    mydc = gdk_fb_cursor_dc_reset();
+
   if(last_cursor)
     {
       if(!last_contents
-        || GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->width != GDK_DRAWABLE_P(last_contents)->width
-        || GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height != GDK_DRAWABLE_P(last_contents)->height)
+        || GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->width > GDK_DRAWABLE_P(last_contents)->width
+        || GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height > GDK_DRAWABLE_P(last_contents)->height)
        {
          if(last_contents)
            gdk_pixmap_unref(last_contents);
@@ -251,15 +279,20 @@ gdk_fb_cursor_unhide(void)
        }
 
       gdk_gc_set_clip_mask(cursor_gc, NULL);
-      gdk_fb_draw_drawable_2(last_contents, cursor_gc, gdk_parent_root, last_location.x, last_location.y, 0, 0,
+      gdk_fb_draw_drawable_2(last_contents, cursor_gc, gdk_parent_root, last_location.x,
+                            last_location.y, 0, 0,
                             GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->width,
                             GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height, TRUE, FALSE);
+      last_contents_size.x = GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->width;
+      last_contents_size.y = GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height;
       gdk_gc_set_clip_mask(cursor_gc, GDK_CURSOR_FB(last_cursor)->mask);
       gdk_gc_set_clip_origin(cursor_gc, last_location.x, last_location.y);
-      gdk_fb_draw_drawable_2(gdk_parent_root, cursor_gc, GDK_CURSOR_FB(last_cursor)->cursor,
+
+      gdk_fb_cursor_dc_reset();
+      gdk_fb_draw_drawable_3(gdk_parent_root, cursor_gc, GDK_CURSOR_FB(last_cursor)->cursor, mydc,
                             0, 0, last_location.x, last_location.y,
                             GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->width,
-                            GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height, TRUE, FALSE);
+                            GDK_DRAWABLE_P(GDK_CURSOR_FB(last_cursor)->cursor)->height);
     }
   else
     gdk_fb_cursor_invalidate();
@@ -299,9 +332,6 @@ move_pointer(PS2Mouse *mouse, GdkWindow *in_window)
 
   gdk_fb_cursor_hide();
 
-  last_location.x = mouse->x;
-  last_location.y = mouse->y;
-
   if(_gdk_fb_pointer_grab_cursor)
     the_cursor = _gdk_fb_pointer_grab_cursor;
   else
@@ -311,6 +341,9 @@ move_pointer(PS2Mouse *mouse, GdkWindow *in_window)
       the_cursor = GDK_WINDOW_FBDATA(in_window)->cursor;
     }
 
+  last_location.x = mouse->x - GDK_CURSOR_FB(the_cursor)->hot_x;
+  last_location.y = mouse->y - GDK_CURSOR_FB(the_cursor)->hot_y;
+
   if(the_cursor)
     gdk_cursor_ref(the_cursor);
   if(last_cursor)
@@ -386,7 +419,7 @@ handle_input(GIOChannel *gioc, GIOCondition cond, gpointer data)
 
   if(dx || dy) {
     GdkEvent *event;
-    gint x, y, rx, ry;
+    gint x, y;
     GdkWindow *win;
     guint state;
 
@@ -582,9 +615,18 @@ gdk_window_find_focus(void)
   if(_gdk_fb_keyboard_grab_window)
     return _gdk_fb_keyboard_grab_window;
   else if(GDK_WINDOW_P(gdk_parent_root)->children)
-    return GDK_WINDOW_P(gdk_parent_root)->children->data;
-  else
-    return gdk_parent_root;
+    {
+      GList *item;
+      for(item = GDK_WINDOW_P(gdk_parent_root)->children; item; item = item->next)
+       {
+         GdkWindowPrivate *priv = item->data;
+
+         if(priv->mapped)
+           return item->data;
+       }
+    }
+
+  return gdk_parent_root;
 }
 
 static gboolean
@@ -623,6 +665,7 @@ handle_keyboard_input(GIOChannel *gioc, GIOCondition cond, gpointer data)
        {'=', '+', 0},
        {GDK_BackSpace, 0, 0},
        {GDK_Tab, 0, 0},
+
        /* 0x10 */
        {'q', 'Q', 0},
        {'w', 'W', 0},
@@ -652,15 +695,15 @@ handle_keyboard_input(GIOChannel *gioc, GIOCondition cond, gpointer data)
        {';', ':', 0},
        {'\'', '"', 0},
        {'`', '~', 0},
-       {0, 0, 0},
        {GDK_Shift_L, 0, 0}, /* mod */
        {'\\', 0, 0},
        {'z', 0, 0},
        {'x', 0, 0},
        {'c', 0, 0},
 
-       /* 0x30 */
        {'v', 'V', 0},
+
+       /* 0x30 */
        {'b', 'B', 0},
        {'n', 'N', 0},
        {'m', 'M', 0},
@@ -669,7 +712,8 @@ handle_keyboard_input(GIOChannel *gioc, GIOCondition cond, gpointer data)
        {'/', 0, 0},
        {GDK_Shift_R, 0, 0}, /* mod */
        {GDK_KP_Multiply, 0, 0},
-       {' ', 0, 0},
+       {0, 0, 0},
+       {GDK_space, 0, 0},
        {0, 0, 0},
        {GDK_F1, 0, 0},
        {GDK_F2, 0, 0},
index 3f8ca53ec78323d44d01b3d3a5ec302568ba773e..296e9b4354f20f5b55995fa8effd2b1dde1378f4 100644 (file)
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <sys/ioctl.h>
-#include <t1lib.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <time.h>
+#include <stdlib.h>
 
 #include "gdk.h"
 
@@ -65,8 +65,6 @@ gdk_fb_display_new(const char *filename)
 {
   int fd, n;
   GdkFBDisplay *retval;
-  guint16 red[256], green[256], blue[256];
-  struct fb_cmap cmap;
 
   fd = open(filename, O_RDWR);
   if(fd < 0)
@@ -78,15 +76,29 @@ gdk_fb_display_new(const char *filename)
   n |= ioctl(fd, FBIOGET_VSCREENINFO, &retval->modeinfo);
   g_assert(!n);
 
-  retval->fbmem = mmap(NULL, retval->sinfo.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+  /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */
+  retval->fbmem = mmap(NULL, retval->modeinfo.yres * retval->sinfo.line_length,
+                      PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
   g_assert(retval->fbmem != MAP_FAILED);
 
-  for(n = 0; n < 16; n++)
-    red[n] = green[n] = blue[n] = n << 12;
-  for(n = 16; n < 256; n++)
-    red[n] = green[n] = blue[n] = n << 8;
-  cmap.red = red; cmap.green = green; cmap.blue = blue; cmap.len = 256; cmap.start = 0;
-  ioctl(fd, FBIOPUTCMAP, &cmap);
+  if(retval->sinfo.visual == FB_VISUAL_PSEUDOCOLOR)
+    {
+      guint16 red[256], green[256], blue[256];
+      struct fb_cmap cmap;
+      for(n = 0; n < 16; n++)
+       red[n] = green[n] = blue[n] = n << 12;
+      for(n = 16; n < 256; n++)
+       red[n] = green[n] = blue[n] = n << 8;
+      cmap.red = red; cmap.green = green; cmap.blue = blue; cmap.len = 256; cmap.start = 0;
+      ioctl(fd, FBIOPUTCMAP, &cmap);
+    }
+
+  if(retval->sinfo.visual == FB_VISUAL_TRUECOLOR)
+    {
+      retval->red_byte = retval->modeinfo.red.offset >> 3;
+      retval->green_byte = retval->modeinfo.green.offset >> 3;
+      retval->blue_byte = retval->modeinfo.blue.offset >> 3;
+    }
 
   return retval;
 }
@@ -94,7 +106,8 @@ gdk_fb_display_new(const char *filename)
 static void
 gdk_fb_display_destroy(GdkFBDisplay *fbd)
 {
-  munmap(fbd->fbmem, fbd->sinfo.smem_len);
+  munmap(fbd->fbmem, fbd->modeinfo.yres * fbd->sinfo.line_length);
+  close(fbd->fd);
   g_free(fbd);
 }
 
@@ -112,8 +125,7 @@ _gdk_windowing_init_check (int argc, char **argv)
   if(!gdk_display)
     return FALSE;
 
-  T1_InitLib(NO_LOGFILE|IGNORE_FONTDATABASE);
-  T1_AASetBitsPerPixel(gdk_display->modeinfo.bits_per_pixel);
+  gdk_fb_font_init();
 
   gdk_initialized = TRUE;
 
@@ -156,14 +168,20 @@ gdk_pointer_grab (GdkWindow *       window,
   g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
 
   if(_gdk_fb_pointer_grab_window)
-    return 1;
+    gdk_pointer_ungrab(time);
 
   if(!owner_events)
     _gdk_fb_pointer_grab_window = gdk_window_ref(window);
 
+  if(cursor)
+    gdk_fb_cursor_hide();
+
   _gdk_fb_pointer_grab_confine = confine_to?gdk_window_ref(confine_to):NULL;
   _gdk_fb_pointer_grab_events = event_mask;
   _gdk_fb_pointer_grab_cursor = cursor?gdk_cursor_ref(cursor):NULL;
+
+  if(cursor)
+    gdk_fb_cursor_unhide();
   
   return 0;
 }
@@ -186,6 +204,11 @@ gdk_pointer_grab (GdkWindow *        window,
 void
 gdk_pointer_ungrab (guint32 time)
 {
+  gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1;
+
+  if(have_grab_cursor)
+    gdk_fb_cursor_hide();
+
   if(_gdk_fb_pointer_grab_window)
     gdk_window_unref(_gdk_fb_pointer_grab_window);
   _gdk_fb_pointer_grab_window = NULL;
@@ -197,6 +220,9 @@ gdk_pointer_ungrab (guint32 time)
   if(_gdk_fb_pointer_grab_cursor)
     gdk_cursor_unref(_gdk_fb_pointer_grab_cursor);
   _gdk_fb_pointer_grab_cursor = NULL;
+
+  if(have_grab_cursor)
+    gdk_fb_cursor_unhide();
 }
 
 /*
@@ -414,7 +440,7 @@ gdk_windowing_exit (void)
 {
   gdk_fb_display_destroy(gdk_display); gdk_display = NULL;
 
-  T1_CloseLib();
+  gdk_fb_font_fini();
 
   keyboard_shutdown();
 }
@@ -431,20 +457,6 @@ gdk_keyval_from_name (const gchar *keyval_name)
   return 0;
 }
 
-void     gdk_keyval_convert_case (guint        symbol,
-                                  guint       *lower,
-                                  guint       *upper)
-{
-  if(symbol >= 'a' && symbol <= 'z')
-    symbol = toupper(symbol);
-
-  if(upper)
-    *upper = symbol;
-
-  if(lower)
-    *lower = symbol;
-}
-
 gchar *
 gdk_get_display(void)
 {
@@ -562,3 +574,57 @@ gdk_event_make(GdkWindow *window, GdkEventType type, gboolean append_to_queue)
 
   return NULL;
 }
+
+void CM(void)
+{
+  static gpointer mymem = NULL;
+  gpointer arry[256];
+  int i;
+
+  free(mymem);
+
+  for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++)
+    arry[i] = malloc(i+1);
+  for(i = 0; i < sizeof(arry)/sizeof(arry[0]); i++)
+    free(arry[i]);
+
+  mymem = malloc(256);
+}
+
+/* XXX badhack */
+typedef struct _GdkWindowPaint GdkWindowPaint;
+
+struct _GdkWindowPaint
+{
+  GdkRegion *region;
+  GdkPixmap *pixmap;
+  gint x_offset;
+  gint y_offset;
+};
+
+void RP(GdkDrawable *d)
+{
+#if 0
+  if(GDK_DRAWABLE_TYPE(d) == GDK_DRAWABLE_PIXMAP)
+    {
+      if(!GDK_PIXMAP_FBDATA(d)->no_free_mem)
+       {
+         guchar *oldmem = GDK_DRAWABLE_FBDATA(d)->mem;
+         guint len = ((GDK_DRAWABLE_P(d)->width * GDK_DRAWABLE_P(d)->depth + 7) / 8) * GDK_DRAWABLE_P(d)->height;
+         GDK_DRAWABLE_FBDATA(d)->mem = g_malloc(len);
+         memcpy(GDK_DRAWABLE_FBDATA(d)->mem, oldmem, len);
+         g_free(oldmem);
+       }
+    }
+  else
+    {
+      GSList *priv = GDK_WINDOW_P(d)->paint_stack;
+      for(; priv; priv = priv->next)
+       {
+         GdkWindowPaint *p = priv->data;
+
+         RP(p->pixmap);
+       }
+    }
+#endif
+}
index 30c6d2bdcbda9b38c2de88bcc08c8df2a12352be..c44089ecfe9724b995f31b68731898ec1bc875f2 100644 (file)
@@ -80,6 +80,7 @@ gdk_fb_pixmap_alloc (void)
   private->klass_data = g_new0 (GdkDrawableFBData, 1);
   private->window_type = GDK_DRAWABLE_PIXMAP;
   private->colormap = gdk_colormap_ref(gdk_colormap_get_system());
+  GDK_DRAWABLE_FBDATA(private)->mem = NULL;
 
   return drawable;
 }
index 2ad3a0489618795419090594c68f18a745cc7058..3ce34f467ee1cd9381bc345d3d0571de60dcc238 100644 (file)
@@ -37,6 +37,7 @@
 #include "gdkregion-generic.h"
 #include <linux/fb.h>
 #include <stdio.h>
+#include <freetype/freetype.h>
 
 #define GDK_DRAWABLE_FBDATA(win) ((GdkDrawableFBData *)(((GdkDrawablePrivate*)(win))->klass_data))
 #define GDK_PIXMAP_FBDATA(win) ((GdkPixmapFBData *)(((GdkDrawablePrivate*)(win))->klass_data))
@@ -46,6 +47,7 @@
 
 typedef struct _GdkDrawableFBData GdkDrawableFBData;
 typedef struct _GdkWindowFBData GdkWindowFBData;
+typedef struct _GdkPixmapFBData GdkPixmapFBData;
 
 struct _GdkDrawableFBData
 {
@@ -87,6 +89,7 @@ struct _GdkFBDisplay
   gulong mem_len;
   struct fb_fix_screeninfo sinfo;
   struct fb_var_screeninfo modeinfo;
+  int red_byte, green_byte, blue_byte; /* For truecolor */
 };
 
 typedef struct {
@@ -104,16 +107,19 @@ typedef struct {
 typedef struct {
   GdkCursor base;
   GdkPixmap *cursor, *mask;
+  int hot_x, hot_y;
 } GdkCursorPrivateFB;
 
 typedef struct {
   GdkFontPrivate base;
 
-  int t1_font_id;
+  FT_Face face;
   double size;
-  GSList *names;
 } GdkFontPrivateFB;
 
+void gdk_fb_font_init(void);
+void gdk_fb_font_fini(void);
+
 typedef struct {
   GdkImagePrivate base;
 } GdkImagePrivateFB;
@@ -156,6 +162,39 @@ void gdk_fb_draw_drawable  (GdkDrawable    *drawable,
                            gint            ydest,
                            gint            width,
                            gint            height);
+
+typedef struct {
+  GdkWindow *bg_relto;
+  GdkPixmap *bgpm;
+
+  GdkRegion *real_clip_region;
+
+  guchar *mem, *clipmem;
+  gpointer cursor_dc;
+
+  guint rowstride, clip_rowstride;
+  int clipxoff, clipyoff;
+
+  gboolean draw_bg : 1;
+  gboolean copy_region : 1;
+  gboolean handle_cursor : 1;
+} GdkFBDrawingContext;
+
+void gdk_fb_drawing_context_init(GdkFBDrawingContext *dc, GdkDrawable *drawable,
+                                GdkGC *gc, gboolean draw_bg, gboolean do_clipping);
+void gdk_fb_drawing_context_finalize(GdkFBDrawingContext *dc);
+
+void gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
+                            GdkGC *gc,
+                            GdkPixmap *src,
+                            GdkFBDrawingContext *dc,
+                            gint xsrc,
+                            gint ysrc,
+                            gint xdest,
+                            gint ydest,
+                            gint width,
+                            gint height);
+
 void gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
                             GdkGC       *gc,
                             GdkPixmap   *src,
@@ -191,4 +230,23 @@ void gdk_fb_redraw_all(void);
 
 void gdk_input_ps2_get_mouseinfo(gint *x, gint *y, GdkModifierType *mask);
 
+#define PANGO_TYPE_FB_FONT              (pango_fb_font_get_type ())
+#define PANGO_FB_FONT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FB_FONT, PangoFBFont))
+typedef struct _PangoFBFont        PangoFBFont;
+struct _PangoFBFont
+{
+  PangoFont parent;
+
+  FT_Face ftf;
+  PangoFontDescription desc;
+  PangoCoverage *coverage;
+  GHashTable *extents;
+};
+GType pango_fb_font_get_type (void);
+gboolean pango_fb_has_glyph(PangoFont *font, PangoGlyph glyph);
+PangoGlyph pango_fb_get_unknown_glyph(PangoFont *font);
+
+extern void CM(void); /* Check for general mem corruption */
+extern void RP(GdkDrawable *drawable); /* Same, for pixmaps */
+
 #endif /* __GDK_PRIVATE_FB_H__ */
index 24468aafdc98a9171d15945d3db8693b81b8a7fe..2bf3d5f2d9ad8a8339670b41bf4be16ad1069f1a 100644 (file)
@@ -66,20 +66,20 @@ gdk_visual_init (void)
       system_visual->colormap_size = 1 << gdk_display->modeinfo.bits_per_pixel;
       system_visual->type = GDK_VISUAL_DIRECT_COLOR;
     case FB_VISUAL_TRUECOLOR:
-      if(gdk_display->sinfo.visual == GDK_VISUAL_TRUE_COLOR)
+      if(gdk_display->sinfo.visual == FB_VISUAL_TRUECOLOR)
        system_visual->type = GDK_VISUAL_TRUE_COLOR;
 
-      system_visual->red_prec = MIN(system_visual->depth / 3, 8);
-      system_visual->red_shift = 0;
-      system_visual->red_mask = ((1 << (system_visual->red_prec + 1)) - 1) << system_visual->red_shift;
+      system_visual->red_prec = gdk_display->modeinfo.red.length;
+      system_visual->red_shift = gdk_display->modeinfo.red.offset;
+      system_visual->red_mask = ((1 << (system_visual->red_prec)) - 1) << system_visual->red_shift;
 
-      system_visual->green_shift = system_visual->red_prec;
-      system_visual->green_prec = MIN(system_visual->depth / 3, 8);
-      system_visual->green_mask = ((1 << (system_visual->green_prec + 1)) - 1) << system_visual->green_shift;
+      system_visual->green_prec = gdk_display->modeinfo.green.length;
+      system_visual->green_shift = gdk_display->modeinfo.green.offset;
+      system_visual->green_mask = ((1 << (system_visual->green_prec)) - 1) << system_visual->green_shift;
 
-      system_visual->blue_shift = system_visual->green_prec + system_visual->green_shift;
-      system_visual->blue_prec = MIN(system_visual->depth / 3, 8);
-      system_visual->blue_mask = ((1 << (system_visual->blue_prec + 1)) - 1) << system_visual->blue_shift;
+      system_visual->blue_prec = gdk_display->modeinfo.blue.length;
+      system_visual->blue_shift = gdk_display->modeinfo.blue.offset;
+      system_visual->blue_mask = ((1 << (system_visual->blue_prec)) - 1) << system_visual->blue_shift;
       break;
     case FB_VISUAL_STATIC_PSEUDOCOLOR:
       system_visual->type = GDK_VISUAL_STATIC_COLOR;
index dad9ff3f35d5ed3ce475ed8bb67420d165171562..4fe2d05cfa5c2b44464e08d0b01fbf5d118286a4 100644 (file)
@@ -116,7 +116,11 @@ gdk_window_init (void)
   private->y = 0;
 
   GDK_DRAWABLE_FBDATA(private)->mem = gdk_display->fbmem;
+#if 0
   GDK_DRAWABLE_FBDATA(private)->rowstride = gdk_display->modeinfo.xres * (gdk_display->modeinfo.bits_per_pixel >> 3);
+#else
+  GDK_DRAWABLE_FBDATA(private)->rowstride = gdk_display->sinfo.line_length;
+#endif
   GDK_DRAWABLE_FBDATA(private)->lim_x = gdk_display->modeinfo.xres;
   GDK_DRAWABLE_FBDATA(private)->lim_y = gdk_display->modeinfo.yres;
   GDK_WINDOW_FBDATA(private)->event_mask = GDK_EXPOSURE_MASK;
@@ -177,7 +181,7 @@ gdk_window_new (GdkWindow     *parent,
   private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
   private->drawable.window_type = attributes->window_type;
   GDK_DRAWABLE_FBDATA(private)->mem = gdk_display->fbmem;
-  GDK_DRAWABLE_FBDATA(private)->rowstride = gdk_display->modeinfo.xres * (gdk_display->modeinfo.bits_per_pixel >> 3);
+  GDK_DRAWABLE_FBDATA(private)->rowstride = GDK_DRAWABLE_FBDATA(gdk_parent_root)->rowstride;
   gdk_window_move_resize (window, x, y,
                          private->drawable.width, private->drawable.height);
 
index 01266650ddb2612d135f6f98ea0444ae1a80e589..e68eaab9a17d491d75c098492cdb1711c04f1177 100644 (file)
@@ -200,6 +200,9 @@ gdk_x11_gc_get_values (GdkGC       *gc,
        case GXset:
          values->function = GDK_SET;
          break;
+       case GXnor:
+         values->function = GDK_NOR;
+         break;
        }
 
       switch (xvalues.fill_style)
@@ -404,6 +407,9 @@ gdk_x11_gc_values_to_xvalues (GdkGCValues    *values,
        case GDK_SET:
          xvalues->function = GXset;
          break;
+       case GDK_NOR:
+         xvalues->function = GXnor;
+         break;
        }
       *xvalues_mask |= GCFunction;
     }
index f1822aabd3ad342ada7becbf81ad3b56ba36a412..326d0702be429cede54280cb425ac89513df7535 100644 (file)
@@ -776,7 +776,7 @@ gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
 }
 
 GdkPixmap*
-gdk_pixmap_foreign_new (guint32 anid)
+gdk_pixmap_foreign_new (GdkNativeWindow anid)
 {
   GdkPixmap *pixmap;
   GdkDrawablePrivate *private;
index b7945760cad680663ed9b3da47b7738026f49ec0..fe6da9b237165f0e261e9a0ec21096a411db83b6 100644 (file)
@@ -435,7 +435,7 @@ gdk_window_new (GdkWindow     *parent,
 }
 
 GdkWindow *
-gdk_window_foreign_new (guint32 anid)
+gdk_window_foreign_new (GdkNativeWindow anid)
 {
   GdkWindow *window;
   GdkWindowPrivate *private;
index d160b21ec7fbd3bb521ee5b85ba62821b386d58b..29d8e8fb4d890ca4df3a48586b990b6ae6e1df01 100644 (file)
@@ -184,12 +184,16 @@ Window        gdk_get_client_window      (Display  *dpy,
                                           Window    win);
 
 /* Functions to create pixmaps and windows from their X equivalents */
-GdkPixmap    *gdk_pixmap_foreign_new (guint32 anid);
-GdkWindow    *gdk_window_foreign_new (guint32 anid);
+GdkPixmap    *gdk_pixmap_foreign_new (GdkNativeWindow anid);
+GdkWindow    *gdk_window_foreign_new (GdkNativeWindow anid);
 
 /* Return the Gdk* for a particular XID */
 gpointer      gdk_xid_table_lookup     (XID              xid);
 
+#define gdk_window_lookup(xid)    ((GdkWindow*) gdk_xid_table_lookup (xid))
+#define gdk_pixmap_lookup(xid)    ((GdkPixmap*) gdk_xid_table_lookup (xid))
+#define gdk_font_lookup(xid)      ((GdkFont*) gdk_xid_table_lookup (xid))
+
 GC _gdk_x11_gc_flush (GdkGC *gc);
 
 #endif /* __GDK_X_H__ */